Solidity中的数据存储位置
你会发现这块内容是最具有挑战性的。下面的表格会是每块数据存储位置的概览,标识了读写的权限。具体每个数据存储位置的详情,可以阅读对应的具体模块。
数据读写权限
我们什么时候使用关键字, storage、memory、calldata ?
任何具有复杂类型的变量比如array,struct,mappings或者enum必须指定一个数据存储位置。
Storage
Storage对应合约内的存储。
你可以把你不想被cloned的变量作为Storage存储。
Storage是长期有效的,但是成本比较高。
Memory
在ETH中memory保存了临时变量,就像函数的参数。
而且,memory变量在外部函数调用时会被清除。
Memory是短暂其便宜的!
Calldata
calldata几乎是免费的,但是有一个长度的限制。
Stack
stack存储了小的局部变量。然而它只能存储数量有限的变量。stack在eth中只能有最大1024个元素。
一旦函数执行完成就结束。
函数参数的数据存储位置规则
下面的表格展示了函数参数可选的数据类型,取决于函数的可见性。
外部函数或者公有函数不能访问storage
函数内部的数据存储位置
在函数内部所有的三种数据存储位置都能被指定,不管函数的可见性。然后在在赋值的时候存在一些具体的规则,如下面表格中展示:
Storage
storage references can be assigned a: | |
---|---|
state variable directly | ✅ |
state variable via storage reference | ✅ |
memory reference | ❌ |
calldata value directly | ❌ |
calldata value via calldata reference | ❌ |
Memory
memory references can be assigned a: | |
---|---|
state variable directly | ✅ |
state variable via storage reference | ✅ |
memoryreference | ✅ |
calldata value directly | ✅ |
calldata value via calldata reference | ✅ |
Calldata
calldata references can be assigned a: | |
---|---|
state variable directly | ❌ |
state variable via storagereference | ❌ |
memoryreference | ❌ |
calldata value directly | ✅ |
calldata value via calldatareference | ✅ |
数据存储位置-行为
当我们指定数据存储位置的时候,有2件主要的事情需要考虑:影响范围和gas的使用量。
让我们用一个简单的合约来更好的了解这个区别。为什么比较不用的存储位置,我们使用了不同的函数使用不同的数据类型关键词。
- a getter storage
- a getter memory
- a setter storage
- a setter memory
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.0;
contract Garage {
struct Item {
uint256 units;
}
mapping(uint256 => Item) items;
// gas (view) 24025
function getItemUnitsStorage(uint _itemIndex) public view returns(uint) {
Item storage item = items[_itemIndex];
return item.units;
}
// gas (view) 24055
function getItemUnitsMemory(uint _itemIndex) public view returns (uint) {
Item memory item = items[_itemIndex];
return item.units;
}
}
作者:师薄零
链接:https://juejin.cn/post/7135437584590700574
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。