在 Solidity 中,有三种数据存储位置:storage、memory 和 calldata。这三者的差异主要在于它们的数据保存位置和存储周期。

  1. Storage: Storage 指的是合约在区块链上的持久存储空间。这类数据会永久存储在区块链上,即使交易被挖矿并添加到区块链后,这些数据也会一直保留。 Storage 是昂贵的,因为它需要使用区块链的磁盘空间。所有的状态变量都存储在 storage 中。
  2. Memory: Memory 数据在临时内存中存储,当前函数执行完毕后,这部分数据就会被清除。Memory 数据不会被永久写入区块链,使用 Memory 比 Storage 成本低。Function 中的局部变量默认在 memory 中。
  3. 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: 恋水无意

腾讯云开发者社区:孟斯特