在Solidity中定义数组后存储的变量在哪些槽中?



所以我知道数组是如何存储的。如果我理解正确的话,它首先在第一个槽中存储数组中的项数,然后在接下来的槽中存储散列值。

我的问题是,如果我在数组之后定义int,并且在部署期间数组只有2个值。所以它应该占3个槽。第四个槽位是我定义的int。

如果有一个函数可以将值压入数组,会怎样?它是如何存储的?

是否存储在下一个空闲槽?或者它会把int值推到下一个槽位并用新值替换它?

我希望这个问题是清楚的,如果不是,我会试着重新措辞。此外,如果有一些好的资源,我可以学习所有关于固体存储,请分享链接。

非常感谢!

固定大小数组按顺序存储其值,从第0个索引开始。没有显示总长度的预加槽。所有未设置的值使用默认值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:默认值为0(未定义第三个地址)
  • 3:_number

动态大小数组将其值存储在属性存储槽的散列键中(在下面的示例中为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: value 2(数组长度)
  • 1:_number
  • 0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563 (int 0的哈希):_addresses[0]
  • 0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e564 (int 0加1的哈希值):_addresses[1]

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


所以回答你的问题:

如果有一个函数将某值压入数组会怎样?它是如何存储的?

是否存储在下一个空闲槽?或者它会把int值推到下一个槽位并用新值替换它?

固定大小的数组不能调整大小。您只能重写它的值,而每个条目的默认值都是0。

对于动态大小的数组,它将新值压入上一个值之后。由于它们存储在索引基于哈希的槽中,因此重写另一个值的概率实际上是0(即,这意味着哈希冲突)。

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

最新更新