I am wanting to read data from internal mappings with the following structures:

mapping (uint256 => uint256) internal nums;
mapping (address => uint256) internal addrToInt;

Finding the memory location of the nums data simply requires uint256(keccak(a, b)), where a is the starting location of the array, and b is the index into the array. In JavaScript we can get this by:

w3.utils.hexToNumberString(w3.utils.soliditySha3(1, 2))

I am finding that this is not the case with the addrToInt mapping. If I run the following Python code:

w3.toInt(w3.soliditySha3(['address', 'uint256'], [addr, idx])) 

then the key leads to an empty storage cell. The same incorrect key is also given with JavaScript:

w3.utils.hexToNumberString(w3.utils.soliditySha3({t: "address", v: addr}, {t: "uint256", v: idx}))

However, this Python code returns the correct key:

w3.toInt(w3.soliditySha3(['address[]', 'uint256[]'], [[addr], [idx]]))

What exactly is going on here by passing the variables as arrays into the function? And I am reading that we cannot pass array types into the web3js soliditySha3 implementation, so is there any way to replicate the above Python code in JavaScript?

1 Answer 1


Use a uint256 for the key instead:

w3.utils.soliditySha3({t: 'uint256', v: addr}, {t: 'uint256', v:idx})

I believe that when computing storage slots, all values get padded to 32 bytes. Treating the address as a uint256 left pads it with zeros.

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.