4

This is asked differently around but I haven't found an explanation as direct as I wanted to.

I've read that all state variables in a contract are publicly visible (solidity docs). It's stated there: "Note that you can never restrict any human or computer from reading the content of your transactions or your contract’s state".

I understand it conceptually but I wonder what steps would be required in order to get the state variables from a contract. Specifically, I've deployed a contract to address 0x8325ba5B0A67745FC6F21DC9A9Cb43f5E8d9c5Df in the Rinkeby test chain. What are the steps required for someone to see the state of my contract? And follow-up, can someone see the functions that contract implements?

1

You can use the eth_getStorageAt rpc method (or web3 function) to get the value at a particular position in storage. In web3 this would look like

web3.eth.getStorageAt("0x8325ba5B0A67745FC6F21DC9A9Cb43f5E8d9c5Df", my_storage_position, "latest")

where my_storage_position is the storage slot of the variable you want (they just increase sequentially by order of declaration).

For example, if your contract starts like this:

contract MyContract {

    address owner;
    uint balance;
    bytes32 data

    ....
}

you would use

eth.getStorageAt(my_address, 0, "latest")

for owner , 1 for balance, 2 for data, etc.

Strings and arrays are a bit trickier. The data actually stored in the normal spot p is the length of the string, and the real string starts at keccak256(p). See the docs for details.

While you cannot tell what the names of functions are, the bytecode is publicly visible, and a determined person could definitely figure out what exactly the contract does. The bytecode can be translated into slightly more readable assembly with tools like https://etherscan.io/opcode-tool.

  • Running web3.eth.getStorageAt("0x8325ba5B0A67745FC6F21DC9A9Cb43f5E8d9c5Df", my_storage_position, "latest") in my geth console connected to Rinkeby returns ReferenceError: 'my_storage_position' is not defined. I'm probably missing something but I didn't quite understand how you'd see, say, and address I have stored in the contract. Also, what would be the steps to convert the bytecode to intelligible information regarding the functioning of the contract? Thanks! – mcansado Jul 19 '17 at 20:46
  • You're supposed to replace my_storage_position with a number, indicating which storage position you want to view – Tjaden Hess Jul 19 '17 at 21:02
  • Awesome, that works now! Sorry to insist but two more things: if I store a string, say "mcansado" in a contract and I run that command, what should I get back (assuming it's the only thing stored in the contract)? And how could I translate that to "mcansado" (assuming it'll return some hex value). And I'm still curious regarding the second part of my comment above: what would be the steps to convert the bytecode to intelligible information regarding the functioning of the contract? – mcansado Jul 19 '17 at 21:09
  • Updated to provide a bit more clarity – Tjaden Hess Jul 19 '17 at 21:16

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.