11

I'm developing a quite complex contract with many state variables of all kinds. (mappings, arrays, uint, strings, bytes, etc).

For testing, it would be very useful to get a JSON (or similar) with the full state of the contract in a given moment.

I would like to know if there is an easy way to get this state from geth or web3.

Some thing like:

var currentState = web3.eth.getFullState([Contract address]);

It would be very good if this method works for any contract of any kind.

  • State is stored as a single mapping from 256 bit ints to 256 bit ints. If you're happy with that internal representation, it's possible to fetch it (though maybe not via the JSON API), but if you want something more helpful like variable names, that's... a little trickier. – Nick Johnson Apr 26 '16 at 6:42
  • Have you checked out test.ether.camp and live.ether.camp - I've linked both URLs to sample contracts. – The Officious BokkyPooBah Apr 30 '16 at 8:44
2

This code can be usfull. It will call all constant methods of contract and print their results. If you make all data members of contract public (in development phase of course) compiller will generate getter methods for you, that will be constant functions. This code will not print mapping and arrays, because getters for them expecting keys or indexes. All constant functions of your contract which have no arguments will be executed. But it is not seems to be a problem - they can not change anything.

function getContractState(abi_object, contract_instance)
{
    "use strict";
    for (let i=0; i<abi_object.length;i++)
    {
        if (abi_object[i].constant==true &&
            abi_object[i].inputs.length==0&&
            abi_object[i].payable==false &&
            abi_object[i].type=="function")
        {
            console.log(abi_object[i].name+"="+contract_instance[abi_object[i].name].call());
        }
    }
}

Example contract:

contract StateTest
{
    uint public u;
    bool public  b;
    int  public  i;
    string public  s;
    byte   public  by;
    bytes  public  bs;
    address public  a;

    function StateTest()
    {
        u=1;
        b=true;
        i=-1;
        s="abc";
        by = 0x13;

        bs=new bytes(2);
        bs[0]=0x11;
        bs[1]=0xff;

        a = msg.sender;
    }
}

Output:

a=0xa90fa13d754131a31cde816fa8ce7ad222d4a246
b=true
bs=0x11ff
by=0x13
s=abc
u=1
i=-1
1

Copy pasting the answer from here: Getting complete state of an smart contract

I've created a repository on Github with an example showing how to read all Patricia trie entries in a block and in any contract storage using nodejs https://github.com/medvedev1088/ethereum-merkle-patricia-trie-example

var Trie = require('merkle-patricia-tree');
var rlp = require('rlp');
var levelup = require('levelup');
var leveldown = require('leveldown');
var db = levelup(leveldown('/your_home_dir/Library/Ethereum/rinkeby/geth/chaindata'));
var keccak256 = require('js-sha3').keccak256;

// the block state root, rinkeby, block number 1775804
// the block state root can be obtained by invoking web3.eth.getBlock(<blockNumber>) in `stateRoot` field
var root = '0xe4a6ff741ec2e0d0cd274a745756028df27312161bdb4557b6da434349f716a9';
var trie = new Trie(db, root);

trie.checkRoot(root, function (err, val) {
  console.log('Root exists:', val);
});

var address = '398A7A69f3c59181A1ffe34bed11DCb5DF863A8a';
var addressHash = keccak256(new Buffer(address, 'hex'));

trie.get('0x' + addressHash, function (err, val) {
  var decodedVal = rlp.decode(val);
  console.log(decodedVal);

  if (!decodedVal || decodedVal.length < 4) {
    console.log('The value for the address must be an array of 4 elements');
    return;
  }

  // 3rd element in the array is storage root, 1st - nonce, 2nd - balance, 4th - codeHash
  var storageRoot = decodedVal[2];
  console.log('storageRoot', storageRoot);

  trie.root = storageRoot;

  trie.checkRoot(storageRoot, function (err, val) {
    console.log('Storage root exists:', val);
  });

  // Read storage slot with index 0

  var slotZeroHash = keccak256(new Buffer('0000000000000000000000000000000000000000000000000000000000000000', 'hex'));
  trie.get('0x' + slotZeroHash, function (err, val) {
    var decodedVal = rlp.decode(val);
    console.log('Value at slot 0: ', decodedVal);
  });

  // Read all entries from contract storage

  var stream = trie.createReadStream();

  stream.on('data', function (data) {
    console.log('key:' + data.key.toString('hex'));

    // values are rlp encoded
    var decodedVal = rlp.decode(data.value);
    console.log(decodedVal);
  });

  stream.on('end', function (val) {
    console.log('done reading!');
  });
});

Example output:

Root exists: true
Account data: 398A7A69f3c59181A1ffe34bed11DCb5DF863A8a [ <Buffer 01>,
  <Buffer >,
  <Buffer 24 21 83 63 90 de b4 32 ce 0e ac fe 5f 49 be 88 99 17 bf 8a fa 07 72 24 1c 30 9e 61 e0 4a 0d 42>,
  <Buffer 61 60 55 49 c9 7c 3e 7a d6 68 63 3b 72 b2 60 d3 00 5e ab be f3 22 a2 d6 33 2a 49 76 80 89 77 7a> ]
Storage root: <Buffer 24 21 83 63 90 de b4 32 ce 0e ac fe 5f 49 be 88 99 17 bf 8a fa 07 72 24 1c 30 9e 61 e0 4a 0d 42>
Storage root exists: true
Value at slot 0 - key: 290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563
<Buffer 40 9f 9c d8 52 a3 ba e9 52 5d 2a aa>
key:0205d9ce8b4a26409d40486b0ac7b8dc356714e840016b19cc5c0f2c8adbcd74
<Buffer 36 35 c9 ad c5 de a0 00 00>
key:0249d346d51fad5ef0b6fae89b4907e63c831f4f8af088d602baef47cda4eab7
<Buffer 0a 07 64 07 d3 f7 44 00 00>

What's interesting is that this data is almost useless because you don't know the slot indexes (you can see only their hashes) and don't know data types of values. At least you know how much storage is occupied by a contract.

0

You should have a look at this forum thread : http://forum.ethereum.org/discussion/2340/is-there-a-way-to-access-ethereum-smart-contracts-variables-by-name-in-javascript where you can finds links to Truffle and Pudding, two tools to abstract contracts and thus manipulate them and look at their state :

Truffle: https://github.com/ConsenSys/truffle

Pudding: https://github.com/ConsenSys/ether-pudding

  • Whilst this may theoretically answer the question, it would be preferable to include the essential parts of the answer here, and provide the link for reference. – Waqar Lim May 3 '16 at 15:06
  • I can't as the answer itself is code of this tools as indicated in my answer. I won't past all the source code in the answer. I already abstracted the content of the linked forum thread as the two links to github are what is important in this thread. So I think my answer comply with stackexchange rules as is. – Nicolas Massart May 3 '16 at 15:19
  • With respect, I think you misunderstood his question, He is not asking how to acess individual variables (like that old forum post is asking), But rather how to get the full state of the contract in one go. @NickJohnson answer is the closest to what he is looking for. I'm pretty sure a dev like jbaylina already knows well tools like Truffle and Embark. – iurimatias Mar 1 '17 at 15:10
  • @iurimatias you are probably right. However I don't have a better answer so feel free to answer if you can. – Nicolas Massart Mar 1 '17 at 16:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.