0

Given the contract variable mapping(address => uint64[]) public foo, can anyone help me access the data using web3?

Assuming we have the account address (0xF89...) and that foo is in slot 5, I can access the length of the array using:

key   = '00000000000000000000000xF895a7D153d80A52aE9C32C30400e000censored'
index = '0000000000000000000000000000000000000000000000000000000000000005'
let varAddress = web3.sha3(key + index, {"encoding":"hex"})   // k . p
let res = web3.eth.getStorageAt(contractAddress, varAddress);

But I haven't been able to figure out how to access the data in the array itself.

I've been trying to decipher the relevant section in Layout of State Variables in Storage, and this article was also helpful, but can't quite get it. Any help?

1

My blog post on the subject has a very similar example: https://programtheblockchain.com/posts/2018/03/09/understanding-ethereum-smart-contract-storage/.

Assuming varAddress is correct (doesn't necessarily look correct from your code, but I imagine that's not an exact copy/paste), you need to hash that location and then add the index. Something like this (untested):

var location = web3.toBigNumber(web3.sha3(varAddress), { encoding: 'hex' })
    .add(n).toString(16);

where n is the index into the array you want to read.

0

Since the mapping is public, Solidity automatically creates a getter for it, you can use it.

let varAddress = web3.sha3(key + index, {"encoding":"hex"})   // k . p
let res = contract.foo(varAddress);

You will need to initialise the contract variable with the web3.eth.Contract function.

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.