Evm

在映射中儲存結構時,如果超出插槽的容量(32 字節),EVM 儲存佈局如何處理?

  • November 7, 2022
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
}
}

在 EVM 儲存佈局中,我知道一個插槽的容量是 32 字節。

如果一個映射將數據儲存在一個槽中,如果結構的結構超過 32 個字節會怎樣?

如果儲存的結構超過一個槽,EVM 將下一個值儲存在slot + 1.

以你的例子:

  1. 您的映射位置為 0。
  2. 映射中項目的插槽儲存在插槽keccak256(abi.encode(key, mapping position))中,您的鍵和映射位置都在其中uint256(0)
  3. 此插槽儲存結構的第一個值。所有其他值都儲存在後面加 1 的插槽中。因此,假設第一個位置將由uint100 表示,下一個值將儲存在插槽 101 中,下一個值將儲存在 102 中,依此類推(這並不完全如果可能,EVM 將嘗試用更多值填充插槽,但您可以在下一部分的範例中看到它)。
  • A:bytes32(uint256(keccak256(abi.encode(uint256(0), uint256(0)))) + 0)
  • 乙+丙:bytes32(uint256(keccak256(abi.encode(uint256(0), uint256(0)))) + 1)
  • d:bytes32(uint256(keccak256(abi.encode(uint256(0), uint256(0)))) + 2)

引用自:https://ethereum.stackexchange.com/questions/138935