在 Solidity 中,有三种数据存储位置:storage、memory 和 calldata。这三者的差异主要在于它们的数据保存位置和存储周期。
- Storage: Storage 指的是合约在区块链上的持久存储空间。这类数据会永久存储在区块链上,即使交易被挖矿并添加到区块链后,这些数据也会一直保留。 Storage 是昂贵的,因为它需要使用区块链的磁盘空间。所有的状态变量都存储在 storage 中。
- Memory: Memory 数据在临时内存中存储,当前函数执行完毕后,这部分数据就会被清除。Memory 数据不会被永久写入区块链,使用 Memory 比 Storage 成本低。Function 中的局部变量默认在 memory 中。
- Calldata: Calldata 用于函数参数,特别是对于 external 函数参数,这类数据只读且在函数调用期间存在。Calldata 在 EVM 中像 memory,但不会被修改,并且在函数调用期间可访问。
下面的示例中展示了三种数据存储位置:
// 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)进行许可,使用时请注明出处。
Author: mengbin
blog: mengbin
Github: mengbin92
cnblogs: 恋水无意
腾讯云开发者社区:孟斯特