storage slot 在 forge-std 中是什么,如何为其设置特定数量?

huangapple go评论57阅读模式
英文:

what is storage slot in forge-std and how to set specific number for it?

问题

我试图基于 forge-std 编写智能合约,并通过 Solidity 编写一些测试,看起来像这样:

    function testOutOfToken() public {
        vm.store(
            address(nftToken),
            bytes32(uint256(7)),
            bytes32(uint256(10000))
        );

        vm.expectRevert(abi.encodeWithSignature("MaxSupplyReached()"));

        nftToken.mintNft{value: 0.15 ether}(1);
    }

第二个参数是 *bytes32(uint256(7))*,根据文档解释如下:

    // 将值存储到地址的存储槽中,(who, slot, value)
    function store(address, bytes32, bytes32) external;
但我仍然不明白 **存储槽** 是什么意思,如果我将 7 更改为其他数字,比如 8,测试就无法通过。有什么想法吗?谢谢!
英文:

I'm try to write smart contract based on forge-std, and writing some test by solidity looks like this:

function testOutOfToken() public {
    vm.store(
        address(nftToken),
        bytes32(uint256(7)),
        bytes32(uint256(10000))
    );

    vm.expectRevert(abi.encodeWithSignature("MaxSupplyReached()"));

    nftToken.mintNft{value: 0.15 ether}(1);
}

the second parameter is bytes32(uint256(7)), from the document is explained like this:

// Stores a value to an address' storage slot, (who, slot, value)
function store(address,bytes32,bytes32) external;

but I still don't understand what storage slot is, if I change the 7 to some other number like 8, the test won't pass. Any idea? Thanks!

答案1

得分: 1

每个合同的属性都可以有一些值,这些值存储在预定位置 - 在预定的插槽中。

对于256位标量类型,插槽ID是通过代码中属性的位置简单计算的。较小的类型被打包到相同的插槽中(在旧版本的Solidity中曾是分开的)。动态类型位于由哈希确定的插槽中。

文档: https://docs.soliditylang.org/en/latest/internals/layout_in_storage.html

pragma solidity ^0.8;

contract MyContract {
    uint256 numberA = 1; // 插槽 0
    uint256 numberB = 1; // 插槽 1
    uint256 numberC = 1; // 插槽 2

    uint128 numberD = 1; // 插槽 3
    uint128 numberE = 1; // 插槽 3

    // 插槽 4 中的长度
    // 插槽ID中的值由位置+偏移的哈希确定
    // 在这种情况下,keccak256(4) + 0, keccak256(4) + 1 和 keccak256(4) + 2
    uint256[] numbers;

    constructor() {
        numbers.push(2);
        numbers.push(3);
        numbers.push(4);
    }
}

如果我将7更改为其他数字,如8,测试将不会通过。

很可能您的测试检查的值存储在插槽ID 7中。而插槽ID 8 包含另一个值(或默认值为0)。由于另一个插槽中没有包含期望的值,测试失败。

英文:

Each property of a contract can have some value, and the value is stored in a predetermined location - in a predetermined slot.

For 256bit scalar types, the slot ID is calculated simply by the property position in the code. Smaller types are packed into the same slot (used to be separate in older Solidity versions). And dynamic types are located in slots determined by a hash.

Docs: https://docs.soliditylang.org/en/latest/internals/layout_in_storage.html

pragma solidity ^0.8;

contract MyContract {
    uint256 numberA = 1; // slot 0
    uint256 numberB = 1; // slot 1
    uint256 numberC = 1; // slot 2

    uint128 numberD = 1; // slot 3
    uint128 numberE = 1; // slot 3

    // length in slot 4
    // values in slot ID determined by hash of the position + offset
    // in this case keccak256(4) + 0, keccak256(4) + 1, and keccak256(4) + 2
    uint256[] numbers;

    constructor() {
        numbers.push(2);
        numbers.push(3);
        numbers.push(4);
    }
}

> if I change the 7 to some other number like 8, the test won't pass

Most likely the value that your test is checking against, is stored in slot ID 7. And slot ID 8 contains some other value (or the default value of 0). Since the other slot doesn't contain the expected value, the test fails.

huangapple
  • 本文由 发表于 2023年2月18日 22:08:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/75493883.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定