在 Solidity 中,有三种数据存储位置:storage、memory 和 calldata。这三者的差异主要在于它们的数据保存位置和存储周期。
1.Storage: Storage 指的是合约在区块链上的持久存储空间。这类数据会永久存储在区块链上,即使交易被挖矿并添加到区块链后,这些数据也会一直保留。 Storage 是昂贵的,因为它需要使用区块链的磁盘空间。所有的状态变量都存储在 storage 中。2.Memory: Memory 数据在临时内存中存储,当前函数执行完毕后,这部分数据就会被清除。Memory 数据不会被永久写入区块链,使用 Memory 比 Storage 成本低。Function 中的局部变量默认在 memory 中。3.Calldata: Calldata 用于函数参数,特别是对于 external 函数参数,这类数据只读且在函数调用期间存在。Calldata 在 EVM 中像 memory,但不会被修改,并且在函数调用期间可访问。
下面的示例中展示了三种数据存储位置:
代码语言:javascript复制// SPDX-License-Identifier: MIT
pragma solidity ^0.8.25;
contract DataLactionsTest {
uint256 storageData; // 状态变量默认存储在 storage, 即链上
function f(uint256 x) external {
uint256 y = x; // 默认存储在 memory,函数执行结束后就被清除
storageData = y x;
}
function g(uint256[] calldata x) external pure returns (uint256) {
return x[1]; // calldata 用于 external 函数参数,只读属性
}
}
在这个例子中,storageData
是一个保存在 storage 的状态变量;在函数 f
中,变量 y
在 memory 中;而函数 g
中,参数 x
是 calldata 类型,仅在函数调用期间可用。
理解这三种数据存储位置之间的差异以及它们如何影响合约的成本,能帮助我们更有效地编写和优化智能合约。如果需要长期存储数据,那么数据应被存储在 storage;否则,如果数据是临时的,它应在 memory 中存储。对于外部函数参数,应优先考虑使用 calldata 来降低 gas 成本。
声明:本作品采用署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)[1]进行许可,使用时请注明出处。 Author: mengbin[2] blog: mengbin[3] Github: mengbin92[4] cnblogs: 恋水无意[5] 腾讯云开发者社区:孟斯特[6]
References
[1]
署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0): https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh
[2]
mengbin: mengbin1992@outlook.com
[3]
mengbin: https://mengbin.top
[4]
mengbin92: https://mengbin92.github.io/
[5]
恋水无意: https://www.cnblogs.com/lianshuiwuyi/
[6]
孟斯特: https://cloud.tencent.com/developer/user/6649301