0
contract test {
 struct StructData {
     address a; // 20 bytes
     uint128 b; // 16 bytes
     uint128 c; // 16 bytes
     bool d; // 1 bytes
 }

 mapping(uint256 => StructData) public MappingData;

 function setMapping() public {
     MappingData[0] = StructData({
         a:address(10), // 20 bytes
         b:444, // 16 bytes
         c:777, // 16 bytes
         d:true// 1 bytes
     });
     // StructData total 20 + 16 + 16 + 1 = 53 bytes
     // exceeded slot's capacity 32 bytes
 }
}

In the EVM storage layout, I know that the capacity of one slot is 32 bytes.

If a mapping stores data in one slot, what happens if the structure of the struct exceeds 32 bytes?

3 Answers 3

1

If the stored struct exceeds one slot, EVM stores the next value in slot + 1.

To your example:

  1. Position of your mapping is 0.
  2. Slot of the item in a mapping is stored in slot keccak256(abi.encode(key, mapping position)), where your key and mapping position are both uint256(0).
  3. This slot stores the first value of the struct. All other values are stored in following slots incremented by 1. Thus, let's say the first position will be represented by uint as 100, the next value is going to be stored in slot 101, the next in 102 and so on (this is not completely true as EVM will try to fill the slot with more values if possible, but you can see it in the next part with your example).
  • a: bytes32(uint256(keccak256(abi.encode(uint256(0), uint256(0)))) + 0)
  • b + c: bytes32(uint256(keccak256(abi.encode(uint256(0), uint256(0)))) + 1)
  • d: bytes32(uint256(keccak256(abi.encode(uint256(0), uint256(0)))) + 2)
0
0

If a mapping stores data in one slot, the structure of the struct is stored elsewhere. The variable MappingData is assigned to storage slot 0 (because that's the first one), but the mapped elements (StrucData in this case) are stored in a different slot by the formula:

slot = keccak256([key, mappingSlot])

which is designated by the keccak256 hash after concatenating the key and mappingSlot. Just because a mapping has been declared, there is no need to store the data in 2^(256)-1 slots.

See:

How does Ethereum fit a mapping into storage?

-1

This article does a pretty good job of showing how the storage layout will look visually with structs, dynamic arrays and mappings.

https://docs.alchemy.com/docs/smart-contract-storage-layout

1
  • Link only answers are discouraged. If for some reason the link changes, they are completely useless.
    – Ismael
    Nov 12, 2022 at 1:42

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.