在固体中阵列后定义的变量是什么插槽?

发布于 2025-01-24 06:25:00 字数 311 浏览 0 评论 0原文

因此,我知道数组是如何存储在存储中的。如果我正确理解它,它首先将项目数存储在第一个插槽中的数组中,然后在下一个插槽中存储Hashed值。

我的问题是,如果我在数组之后定义UINT,而部署过程中的数组只有2个值。因此,它应该占用3个插槽。然后在第四个插槽中是我定义的UINT。

如果有可以将某些东西推向数组的函数怎么办?如何存储?

它会存储在下一个免费插槽中吗?还是将UINT推到下一个插槽并用新值替换?

我希望这个问题很清楚,我是否会尝试重新提示它。 另外,如果有一些很好的资源,我可以在固体中了解所有有关存储的信息,请分享链接。

多谢!

So I know how arrays are stored in storage. If I understand it correctly it first stores the number of items in an array in the first slot, and then in the next slots, it stores the hashed values.

My question is what if I define uint after the array and the array during deployment has only 2 values. So it should take up 3 slots. Then in the fourth slot is the uint I defined.

What if there is a function that will push something to the array? How is it stored?

Will it be stored in the next free slot? Or will it push the uint to the next slot and replace it with the new value?

I hope the question is clear if not I will try to rephrase it.
Also if there is some good resource where I can learn all about storage in solidity please share the link.

Thanks a lot!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

小耗子 2025-01-31 06:25:00

固定大小的数组以顺序排列的顺序存储其值,从0th Index开始。没有预先验证的插槽可以显示总长度。任何未设置的值使用默认值为0。

pragma solidity ^0.8;

contract MyContract {
    address[3] addresses; // storage slots 0, 1, 2
    uint256 number; // storage slot 3

    constructor(address[2] memory _addresses, uint256 _number) {
        addresses = _addresses;
        number = _number;
    }
}

将2个地址传达给构造函数,在这种情况下,存储插槽值:

  • 0:_addresses [0]
  • 1:_ADDRESSES [1]
  • 2:零的默认值(未定义第三个地址)
  • 3:_number

Dynamic-size数组将其值存储在属性存储插槽的键中(例如下面的示例为0,因为那是第一个存储属性),并立即在插槽之后。在属性存储插槽中,它存储数组长度。

pragma solidity ^0.8;

contract MyContract {
    /*
     * storage slots:
     * p (in this case value 0, as this is the first storage property) = length of the array
     * keccak256(p) = value of index 0
     * keccak256(p) + 1 = value of index 1
     * etc.
     */
    address[] addresses;

    // storage slot 1
    uint256 number;

    constructor(address[] memory _addresses, uint256 _number) {
        addresses = _addresses;
        number = _number;
    }
}

在这种情况下,将2个地址传达给构造函数,存储插槽值:

  • 0:值2(数组的长度)
  • 1:_number
  • 0x290DECD9548B62A8D60345A9886FC84BA6FC84BA6BC954BA6BC95484848484008F6362F933161616160.NE h. ] < /代码>
  • 0x290DECD9548B62A8D60345A988386FC84BA6BC95484008F6362F93160EF3E564(UINT 0,PLUS 1) v0.8.13/internals

/ layout_in_storage.html#mappings-and-dynamic-arrays" rel="nofollow noreferrer">https://docs.soliditylang.org/en/v0.8.13/internals/layout_in_storage.html#mappings-and-dynamic-arrays


所以回答您的问题:

如果有一个函数将某些东西推到数组中怎么办?如何存储?

是否将其存储在下一个免费插槽中?还是将UINT推到下一个插槽并用新值替换?

固定大小数组无法调整。您只能重写其值,而每个项目的默认值为0。

如果是动态大小数组,它将在最后一个之后按新值。由于它们存储在索引基于哈希的插槽中,因此重写另一个值的可能性实际上是0(即,这意味着哈希碰撞)。

在这两种情况下,它都不会影响其他存储属性的存储方式。

Fixed-size array stores its values in sequential order, starting with the 0th index. There's no prepended slot that would show the total length. Any unset values use the default value of 0.

pragma solidity ^0.8;

contract MyContract {
    address[3] addresses; // storage slots 0, 1, 2
    uint256 number; // storage slot 3

    constructor(address[2] memory _addresses, uint256 _number) {
        addresses = _addresses;
        number = _number;
    }
}

Passing 2 addresses to the constructor, storage slot values in this case:

  • 0: _addresses[0]
  • 1: _addresses[1]
  • 2: default value of zero (third address was not defined)
  • 3: _number

Dynamic-size array stores its values in keys that are hash of the property storage slot (in example below that's 0, as that's the first storage property), and immediately following slots. In the property storage slot, it stores the array length.

pragma solidity ^0.8;

contract MyContract {
    /*
     * storage slots:
     * p (in this case value 0, as this is the first storage property) = length of the array
     * keccak256(p) = value of index 0
     * keccak256(p) + 1 = value of index 1
     * etc.
     */
    address[] addresses;

    // storage slot 1
    uint256 number;

    constructor(address[] memory _addresses, uint256 _number) {
        addresses = _addresses;
        number = _number;
    }
}

Passing 2 addresses to the constructor, storage slot values in this case:

  • 0: value 2 (length of the array)
  • 1: _number
  • 0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563 (hash of uint 0): _addresses[0]
  • 0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e564 (hash of uint 0, plus 1): _addresses[1]

Docs: https://docs.soliditylang.org/en/v0.8.13/internals/layout_in_storage.html#mappings-and-dynamic-arrays


So to answer your questions:

What if there is a function that will push something to the array? How is it stored?

Will it be stored in the next free slot? Or will it push the uint to the next slot and replace it with the new value?

Fixed-size arrays cannot be resized. You can only rewrite its values, while the default value of each item is 0.

In case of dynamic-size arrays, it pushes the new value right after the last one. Since they are stored in slots which indexes are based on a hash, the probability of rewriting another value is practically 0 (i.e. that would mean a hash collision).

In both cases, it doesn't affect how other storage properties are stored.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文