I'm trying to check where is stored a string in storage in Solidity.
For testing this I'm using this code:
pragma solidity 0.5.4;
contract AssemblyString {
string s; // slot 0
function set(string calldata _s) external {
s = _s;
}
function get(uint i) public view returns (bytes32){
bytes32 r;
assembly {
r := sload(i) //we load the slot number i
}
return r;
}
}
If I set string less than 31 bytes works fine as solidity specifies:
- Deploy contract
- set("ether")
- get(0)
Output: 0x657468657200000000000000000000000000000000000000000000000000000a
The first part stands for the encoded string: 0x6574686572 equals "ether".
The second part is the size*2: 0xA equals 10 in decimal. (ether has 5 letters, then 5 times 2 equals 10)
All the zeros in between are padded to reach 32 bytes long.
But! if I set string more than 31 bytes, I can't find the string.
As the specification says, the data of the string is contained in the keccak256(slot).
When I search for
keccak256(0) = 044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d
To decimal:
1937035142596246788172577232054709726386880441279550832067530347910661804397
Output: 0x0
But if I debug the contract in Remix IDE, I found that the data is stored always in key 0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563,
dec: 18569430475105882587588266137607568536673111973893317399460219858819262702947
and the string is stored at that position.
What I'm doing wrong?
Thank you for your time.