7

With web3, I can access the history of the blockchain like this:

web3.eth.getBalance('0x1234') // returns current balance at address 0x1234
web3.eth.getBalance('0x1234', 1000) // returns balance at block 1000

Cf. https://github.com/ethereum/wiki/wiki/JavaScript-API#web3ethdefaultblock

I have not been able to find anything similar in Solidity. Is there a corresponding pattern in Solidity? Or in EVM bytecode? Or fundamental reasons why it cannot be done?

7

No, Solidity code (and EVM code in general) is only able to read the current state at the block at which it is being called. If it were able to read state at previous blocks you would need the entire history of the blockchain to validate a block. By not allowing this, the Ethereum developers made it possible to validate a block with only the current state, which is a much less demanding requirement.

In theory it should be possible to construct a Merkle proof that an address had a particular state at a particular block, and pass in the requisite data to allow a contract to verify this proof. That way the caller of a contract could fetch the old data as you do in your example with Web3 and the Solidity code could get that data as a parameter, verify that it was real and act accordingly. However, this probably isn't a trivial thing to do, and I don't know of any examples of it being done.

If you need a history of state at previous blocks the normal solution is to explicitly store this history in contract storage, and add to your history data every time you make a change.

  • I see the point about it being desirable to be able to validate a block with only the current state. But if cost/speed is an issue, would it not have been better to add an opcode and make it (very) expensive, instead of limiting the EVM in such a fundamental way? – gellej Jan 23 '17 at 10:15
  • 1
    It's not just that it's onerous to read the set of all previous states, it's onerous to actually be required to have it in the first place, so making it expensive wouldn't solve the problem. – Edmund Edgar Jan 23 '17 at 10:32
  • From my understanding, each full node already "has" all the history in the sense that it can reconstruct it from the genesis block and the transaction history (my local node has no problem reconstructing intermediate states if i query it with web3). (Perhaps i'm now asking for the motivations of the designers of the EVM, and perhaps this is not the right place to ask :-) – gellej Jan 24 '17 at 11:15
  • A full node does, but a light node doesn't. Also iiuc with sharding, full nodes of one shard will be light nodes of another. – Edmund Edgar Jan 24 '17 at 12:02
2

Yes, it is possible with Web3 at any given block.

If your contract has:

contract ValueStore {
    function getValue(uint param) constant returns (uint returnedValue);
}

Then, after instantiating your Web3 contract, you can do:

valueStoreInstance.getValue.call(param, blockNumber, function(error, returnedValue) { });
  • Please answer whether its possible or not? – niksmac Jan 21 '17 at 2:22
  • I gave you some code for Web3. This code works. So yeah, it's possible for Web3. – Xavier Leprêtre B9lab Jan 21 '17 at 10:51
  • 4
    thanks, but that was not what I was asking. my question is whether it is possible to do a similar thing in solidity (i.e. in the EVM) – gellej Jan 21 '17 at 18:46

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.