Ethereum JSON_RPC eth_getStorageAt

Create a simple contract:


contract Storage {
    uint pos0;
    mapping(address => uint) pos1;
    
    function Storage() {
        pos0 = 1234;
        pos1[msg.sender] = 5678;
    }
}

submit it and get back address. In example 0x9a5CdfCb1132dcbEca55b213372224D9bd0209c2

Now lets execute it under one account. In example 0xa2213890a81042692B4716025D6e98349b432349

Lets see how we can get what is in storage related with contract.

We can use JSON_RPC eth_getStorageAt or web3.eth.getStorageAt from geth command line. In this example I’ll use JSON_RPC eth_getStorageAt.

Contracts storage is basically key-value storage.

To get pos0 is simple:

margusja@IRack:~$ curl -X POST --data '{"jsonrpc":"2.0", "method": "eth_getStorageAt", "params": ["0x9a5CdfCb1132dcbEca55b213372224D9bd0209c2", "0x0", "latest"], "id": 1}' localhost:8545
{"jsonrpc":"2.0","id":1,"result":"0x00000000000000000000000000000000000000000000000000000000000004d2"}

hex value 4d2 to decimal is 1234.

TO get pos1 is more tricky. First we have to calculate index position using contract executor address and index. Go to geth commandline and:

var key = “000000000000000000000000a2213890a81042692B4716025D6e98349b432349″ + “0000000000000000000000000000000000000000000000000000000000000001”

We added zeros to get 64 bit value. Next in geth command line:

web3.sha3(key, {“encoding”: “hex”}) – it returns aadress: 0x790e4fae970c427bd6d93e3f64ba898c69fdead01d68e500efb6f3abc672d632

Now we can get value from storage:

margusja@IRack:~$ curl -X POST --data '{"jsonrpc":"2.0", "method": "eth_getStorageAt", "params": ["0x9a5CdfCb1132dcbEca55b213372224D9bd0209c2", "0x790e4fae970c427bd6d93e3f64ba898c69fdead01d68e500efb6f3abc672d632", "latest"], "id": 1}' localhost:8545
{"jsonrpc":"2.0","id":1,"result":"0x000000000000000000000000000000000000000000000000000000000000162e"}

hex value 162e to decimal is 5678

Source – https://github.com/ethereum/wiki/wiki/JSON-RPC#web3_clientversion