-
Notifications
You must be signed in to change notification settings - Fork 5.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rule for string->uint mapping and the storage position #1550
Comments
Since strings are arbitrary length, you have to hash them first. |
I still cannot get the correct hash value "69e08a2904d77becc5ebdff9265102784e25436cf0dfbaeb5c932ed98ffc834d", could you help check whether I miss anything? var key0 = "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000616161" sha3 : "0x8f34d90832af21f9fc31ef2888a966ad8090cdd9bc1a16ecf819059d118ae6db" var key0 = "616161" sha3 : "0xe4998bf274557cf66b8123e4803a12c6dca7f047052b01d6b4b51776b0eb04d7" var key0 = "0000000000000000000000000000000000000000000000000000000000616161" sha3 : "0x4b9ff950998e1bfecbf6ed1b5e7531fee7fac216130cafe3d3c03d0b1ba697b8" |
I would try the array access in the browser-solidity, and chase the stack & memory contents. |
We are going to use getStorageAt() API, which requires the storage slot as parameter, so have to do sha3 hash to get the exact storage slot, so could you kindly help on this? |
And, in fact, we need to use mapping in this way "mapping(string=>MyStruct)", and found the correct storage slot cannot be got, then simply the mapping to "mapping(string=>uint)" in this posting for easy reading/debugging. |
For your purpose, you can define
and call the function from web3. |
Ah, I think your original version was fine except for padding the key. So I think the following should work: var key = "616161"
var pos = "0000000000000000000000000000000000000000000000000000000000000000"
web3.sha3(key + pos, {"encoding":"hex"}) |
Awesome, it works, thanks a lot! |
@hievan2016 @chriseth is there anyway to return an element of a mapping without knowing the key but using an index (i.e. pos 1, 2, etc)? Carrying on your example from above, if Assuming we did not know the keys but we knew that i2s was in position 2? I have worked out how to do this for arrays but not for maps. Thanks Ian |
@ianmonkuk you will have to create an iterated mapping. Search for it in the readthedocs page. You'll get the idea. |
@ianmonkuk please ask on http://gitter.im/ethereum/solidity or on http://ethereum.stackexchange.com |
@VoR0220 thanks for responding. I should have clarified that I need to do this in the same way as discussed in this thread - using getStorageAt function which @hievan2016 was using. I am aware that this can be done relatively easily within the contract itself. @chriseth there's been a lot of questions relate to this on stackexchange and they all point to the page below. This seems to suggest access to map elements (via getStorageAt) can only be accessed if the keys are known. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage Thanks, Ian |
Yes, you have to know the hash of the key. Some clients can also list storage contents and you might be able to derive the keys from there. |
Ok, understood, thanks @chriseth. Do you know if Geth lists the storage
contents? Cheers, Ian
Thanks,
Ian
|
It is a bit tricky, because there is another hash function evaluation envolved. If you did a full sync, yes. If you fast-synced, you might not have all values, but I think the geth team is currently building a remote server where you can get the missing values. |
ok thanks |
I have a question:
} and I have been deploy this contract used by Remix,then invoke the test1() method. I debug this function In Debugger ,so Can see
I know the hash 0x28a06524829b6fed74df277d29b0e9d5843614df83ac4257ee812125675fdd54 and 0x4a9ab6c152794dd891130d65b49535f6222d24e4c9a3f06f616c3634b24c9fac, |
Env
solc --version
solc, the solidity compiler commandline interface
Version: 0.4.7+commit.822622cf.Linux.g++
./geth version
Geth
Version: 1.4.7-stable-667a386d
Protocol Versions: [63 62 61]
Network Id: 1
Go Version: go1.5.4
OS: linux
Problem
We are trying to figure out the mapping rule and storage position of saved data
base on this formula
keccack(LeftPad32(key, 0), LeftPad32(map position, 0))
which is mentioned at
https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getstorageat
however, seems this works for uint->string mapping, but not for string->uint
mapping, could anyone pls help on this?
Below is the test contract
contract testMapping{
mapping(string=>uint) s2i; //position is 0
mapping(uint=>string) i2s; //position is 1
}
then we use the mapping to save the data by calling
setStr("aaa") // key is aaa (ascii : 616161)
setInt(200) // key is 200 (hex : c8)
the contract storage is
storage: {
345f7c6c888721344af4147de0834159e0b302300ba13c4e7b6c0b60d8f2314e: "a07a7a7a0000000000000000000000000000000000000000000000000000000006",
69e08a2904d77becc5ebdff9265102784e25436cf0dfbaeb5c932ed98ffc834d: "64"
}
the first entry shows "zzz" (ascii : 7a7a7a) is saved at position "345f7c6c888721344af4147de0834159e0b302300ba13c4e7b6c0b60d8f2314e",
this position could be got from the formula.
but when using "aaa" as the key to do string->uint mapping to save value 100 (0x64),
we cannot get the correct storage position "69e08a2904d77becc5ebdff9265102784e25436cf0dfbaeb5c932ed98ffc834d"
based on the formula, you can see, the sha3 value is incorrect.
var key = "0000000000000000000000000000000000000000000000000000000000616161" + "0000000000000000000000000000000000000000000000000000000000000000"
web3.sha3(key, {"encoding":"hex"})
"0x15b5515e45c94bd2fbc0aa103673f2c4899d2996fe1407ba1e6e5ef9ac66c2f5"
The text was updated successfully, but these errors were encountered: