3

I have a private chain and I am running own archiving node. The node connected with --fast cache=1024 option.

For example I have a set function on my smart contract.

contract smartContract {
    uint  value;
    function set(uint input) returns (bool success) {
         value = input;
    }
    function getValue() public view
     returns (uint)
    {
        return value;
    } 

}

This function is called at block number 100 and 200.

smartContract.set(10) //deployed at block number 100
smartContract.set(20) //deployed at block number 200

At this point. if our blockchain is sync, as we know, when we call smartContract.get() it returns 20.

Here mentions that smart contact can only see the current state.

A contract can only see the current state when it executes, not previous states. This restriction allows validating nodes to work only with the current state, rather than needing to store and be able to access all the previous states.

Here we can get previous blocks data. Since we can obtain previous block data, we could obtain the previous states.

[Q] Could web3 retrieve state of a value from previous block numbers instead of returning the its latest state value?

If we provide the block number such as 100, smartContract.get() at 100; somehow can web3 return value's value at block number 100 instead at latest?

8
  • 2
    web3.js 0.2 can
    – Henk
    Commented May 1, 2018 at 11:36
  • How? I couldn't find the specific example on the link you share. How about web3.py ? @Henk
    – alper
    Commented May 1, 2018 at 11:38
  • 1
    An alternative might be to fire an event when the state variable is changed.
    – Jesbus
    Commented May 1, 2018 at 12:43
  • That's possible but I want to take event out of the table, since it has been already been stored in the memory, and I don't want consume additional gas for the event. @Jesse Busman
    – alper
    Commented May 1, 2018 at 12:50
  • @Alper When you make a query you can pass an extra parameter with the block number, default is 'latest' but you can pass 'pending' or an explicit block number/hash. The issue is that non-archive clients will only have the more recent 256 states, querying a block beyond that range will return an error.
    – Ismael
    Commented May 1, 2018 at 15:05

1 Answer 1

3

[Q] Could web3 retrieve state of a value from previous block numbers instead of returning the its latest state value?

Yes, in web3.py v4.0+.

When making a contract call, you can specify a block number (or hash). These examples are from the web3.py docs:

# You can call your contract method at a block number:
>>> token_contract.functions.myBalance().call(block_identifier=10)

# or a number of blocks back from pending,
# in this case, the block just before the latest block:
>>> token_contract.functions.myBalance().call(block_identifier=-2)

# or a block hash:
>>> token_contract.functions.myBalance().call(block_identifier='0x4ff4a38b278ab49f7739d3a4ed4e12714386a9fdf72192f2e8f7da7822f10b4d')
>>> token_contract.functions.myBalance().call(block_identifier=b'O\xf4\xa3\x8b\'\x8a\xb4\x9fw9\xd3\xa4\xedN\x12qC\x86\xa9\xfd\xf7!\x92\xf2\xe8\xf7\xdax"\xf1\x0bM')

# Latest is the default, so this is redundant:
>>> token_contract.functions.myBalance().call(block_identifier='latest')

# You can check the state after your pending transactions (if supported by your node):
>>> token_contract.functions.myBalance().call(block_identifier='pending')
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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