Solidity中定义在数组后面的变量存储在哪些槽中?
In what slots are variables stored that are defined after an array in Solidity?
所以我知道数组在存储中是如何存储的。如果我理解正确的话,它首先将数组中的项目数存储在第一个插槽中,然后在下一个插槽中存储散列值。
我的问题是,如果我在数组之后定义 uint 并且部署期间的数组只有 2 个值怎么办?所以它应该占用3个插槽。然后在第四个槽是我定义的uint。
如果有一个函数可以将某些内容推送到数组怎么办?它是如何存储的?
它会存储在下一个空闲插槽中吗?还是会将 uint 推送到下一个插槽并用新值替换它?
我希望问题很清楚,否则我会尝试重新表述。
另外,如果有一些好的资源可以让我了解关于存储的所有知识,请分享 link.
非常感谢!
Fixed-size 数组按顺序存储其值,从第 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:默认值为零(第三个地址未定义)
- 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
- 0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563(uint 0 的哈希值):
_addresses[0]
- 0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e564(uint 0 的哈希,加 1):
_addresses[1]
所以回答你的问题:
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 数组无法调整大小。您只能改写它的值,而每一项的默认值为0。
在 dynamic-size 数组的情况下,它会将新值推入最后一个值之后。由于它们存储在索引基于散列的插槽中,因此重写另一个值的概率实际上为 0(即这意味着散列冲突)。
在这两种情况下,它都不会影响其他存储属性的存储方式。
所以我知道数组在存储中是如何存储的。如果我理解正确的话,它首先将数组中的项目数存储在第一个插槽中,然后在下一个插槽中存储散列值。
我的问题是,如果我在数组之后定义 uint 并且部署期间的数组只有 2 个值怎么办?所以它应该占用3个插槽。然后在第四个槽是我定义的uint。
如果有一个函数可以将某些内容推送到数组怎么办?它是如何存储的?
它会存储在下一个空闲插槽中吗?还是会将 uint 推送到下一个插槽并用新值替换它?
我希望问题很清楚,否则我会尝试重新表述。 另外,如果有一些好的资源可以让我了解关于存储的所有知识,请分享 link.
非常感谢!
Fixed-size 数组按顺序存储其值,从第 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:默认值为零(第三个地址未定义)
- 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
- 0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563(uint 0 的哈希值):
_addresses[0]
- 0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e564(uint 0 的哈希,加 1):
_addresses[1]
所以回答你的问题:
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 数组无法调整大小。您只能改写它的值,而每一项的默认值为0。
在 dynamic-size 数组的情况下,它会将新值推入最后一个值之后。由于它们存储在索引基于散列的插槽中,因此重写另一个值的概率实际上为 0(即这意味着散列冲突)。
在这两种情况下,它都不会影响其他存储属性的存储方式。