1

I'm trying to save in storage some values in a nested mapping. Found some results of a similar problem, tried the solutions, but no success, also read the documentation of https://docs.soliditylang.org/en/v0.8.17/internals/layout_in_storage.html but still did not figured out what is wrong.

This is the complete code:

pragma solidity ^0.8.0; import "hardhat/console.sol"; contract Spiral { struct Chunk { int256 x; int256 y; } // 0: right, 1: down, 2: left, 3: up bytes1 directionB = 0x00; uint256 currentTravel = 1; uint256 stepCounter = currentTravel; Chunk[] public chunks; mapping(int256 => mapping(int256 => uint256)) public XYtoChunkId; constructor() { // Start the spiral at the origin (0, 0) chunks.push(Chunk(0, 0)); XYtoChunkId[0][0] = 0; } function addChunk() public { int256 x; int256 y; uint256 chunkId; assembly { let r := sload(chunks.slot) mstore(0x00, chunks.slot) let chunks_pt := keccak256(0x00, 0x20) let p := add(mul(sub(r, 1), 2), chunks_pt) x := sload(p) y := sload(add(p, 1)) let new_r := add(r, 1) let new_p := add(mul(r, 2), chunks_pt) sstore(chunks.slot, new_r) switch sload(directionB.slot) case 0x00 { sstore(new_p, add(x, 1)) sstore(add(new_p, 1), y) } case 0x01 { sstore(new_p, x) sstore(add(new_p, 1), sub(y, 1)) } case 0x02 { sstore(new_p, sub(x, 1)) sstore(add(new_p, 1), y) } case 0x03 { sstore(new_p, x) sstore(add(new_p, 1), add(y, 1)) } sstore(stepCounter.slot, sub(sload(stepCounter.slot), 1)) if eq(sload(stepCounter.slot), 0x00) { sstore( directionB.slot, addmod(sload(directionB.slot), 0x01, 0x04) ) sstore(stepCounter.slot, sload(currentTravel.slot)) switch sload(directionB.slot) case 0x01 { sstore( currentTravel.slot, add(sload(currentTravel.slot), 1) ) } case 0x03 { sstore( currentTravel.slot, add(sload(currentTravel.slot), 1) ) } } mstore(0x00, x) mstore(0x20, XYtoChunkId.slot) let xHash := keccak256(0x00, 0x40) mstore(0x00, y) mstore(0x20, xHash) let chunkIdSlot := keccak256(0x00, 0x40) chunkId := sload(chunkIdSlot) sstore(chunkIdSlot, sub(r, 2)) } console.log(chunkId); // XYtoChunkId[x][y] = chunks.length - 2; } } 

I am trying to add the chunkId which is r - 2 in the mapping storage mapping(int256 => mapping(int256 => uint256)) public XYtoChunkId; using this part of the code

mstore(0x00, x) mstore(0x20, XYtoChunkId.slot) let xHash := keccak256(0x00, 0x40) mstore(0x00, y) mstore(0x20, xHash) let chunkIdSlot := keccak256(0x00, 0x40) chunkId := sload(chunkIdSlot) sstore(chunkIdSlot, sub(r, 2)) 

Adapted this part from a similar question on the forum, no success, also tried to play around and switching order of x and y when keccak256, was getting some id's back , but not the correct ones. Thanks.

5
  • it is not clear what you mean by "no success", are you implying that sstore instruction doesn't save the value at specified location? that's not true Commented Dec 21, 2022 at 19:03
  • sstore gets the location and value from the stack, where are you pushing it? Commented Dec 21, 2022 at 19:06
  • by no success i mean when i console log chunkId i get 0 , instead of real values. sstore saves to storage if i'm not wrong, sload gets the value from the storage. The last part of the code that i mentioned should produce the same result as XYtoChunkId[x][y] = chunks.length - 2; but it does not. After executing the function and calling XYtoChunkId[x][y] I get 0 back instead of a real Id Commented Dec 21, 2022 at 20:25
  • run a trace and verify that the stack contains correct location and value just before SSTORE opcode is executed. if you store some value but get 0 when reading it, then it means you are giving it wrong location either at write or read operation Commented Dec 22, 2022 at 1:44
  • please stop, you're not helping, of course it's the wrong location i mentioned that i'm using the formula provided in the docs to calculate the storage location of a nested mapping, but value it's not getting inserted there Commented Dec 22, 2022 at 4:22

1 Answer 1

0

It is zero because in the constructor you stored zero XYtoChunkId[0][0] = 0.

chunkId := sload(chunkIdSlot) sstore(chunkIdSlot, sub(r, 2)) 

If you want to get the updated value, you have to read the slot after the modification

sstore(chunkIdSlot, sub(r, 2)) // <--- modification chunkId := sload(chunkIdSlot). // <--- read 

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.