Solidity 中的数据存储位置(Data Location)主要有 三个关键修饰符:
| 修饰符 | 存储位置 | 特点 | 使用场景 |
|---|---|---|---|
| storage | 链上持久化存储(State Storage) | 成本高、持久保存、所有合约共享同一份状态 | 状态变量、结构体引用、映射、数组等 |
| memory | 内存区(函数执行期间存在) | 成本中等、临时的、函数结束即销毁 | 函数内部变量、临时数组、字符串处理 |
| calldata | 只读、不可修改、存在于外部调用数据中 | Gas 成本最低(特别是数组/字符串)、只读 | 函数参数(external),节省 Gas |
storage链上持久化存储,Gas 最贵。
SOLIDITY1uint[] public arr; // storage 2 3function f() public { 4 uint[] storage ref = arr; // 引用状态变量 5 ref.push(1); 6}
storage 会写入链上 → 费用高storagememory临时存储,只在函数执行期间存在。
SOLIDITY1function f(uint[] memory values) public pure { 2 values[0] = 123; // 可读可写,但不会写入链上 3}
storage 的引用类型本地变量calldata只读、不可修改,外部调用参数所在位置,最省 Gas。
SOLIDITY1function f(uint[] calldata values) external { 2 uint v = values[0]; // 只读 3}
优点:
| 项目 | storage | memory | calldata |
|---|---|---|---|
| 生命周期 | 永久 | 函数执行期 | 函数调用期 |
| 可写 | ✔ | ✔ | ✖ |
| Gas 成本 | 💰💰💰(最高) | 💰💰 | 💰(最低) |
| 典型使用 | 状态变量、修改链上数据 | 本地变量、纯函数处理 | external 函数的数组/字符串参数 |
external → 用 calldataSOLIDITY1function process(uint[] calldata arr) external { 2 ... 3}
memorystorage