区块链Mar 28, 2026
Deep EVM #3:理解Gas——你的合约为何如此昂贵
OS
Open Soft Team
Engineering Team
Gas不是抽象概念
开发者经常将gas视为一个模糊的“成本“指标。实际上,gas是一个精确定义的资源核算系统,有确切的公式。每个操作码、每字节calldata、每次存储访问都有在黄皮书和后续EIP中确定性定义的gas成本。
理解这些成本将gas优化从猜测变为工程。
固有Gas:基线
在你的合约代码执行任何操作码之前,交易已经消耗了gas。这就是固有gas:
intrinsic_gas = 21000 // 基础交易成本
+ 16 * nonzero_calldata_bytes // 每个非零字节
+ 4 * zero_calldata_bytes // 每个零字节
+ access_list_cost // 如果有EIP-2930访问列表
+ 32000 (如果是合约创建) // 仅CREATE交易
EIP-2929:访问列表革命
EIP-2929引入了每笔交易的访问集合。首次触及地址或存储槽时是“冷“的,需要支付冷访问附加费。后续访问是“热“的,价格便宜。
冷 vs 热Gas成本
| 操作码 | 冷 | 热 | 节省 |
|---|---|---|---|
| SLOAD | 2100 | 100 | 2000 |
| SSTORE | +2100冷附加费 | 仅基础成本 | 2100 |
| CALL | 2600 | 100 | 2500 |
SSTORE:最复杂的操作码
SSTORE的gas成本取决于三个因素:原始值(交易开始时)、当前值和新值。
关键洞察:将零槽设置为非零消耗20000 gas,而修改现有非零槽消耗2900 gas(热访问)。这7倍的差异解释了为什么初始化映射代价高昂。
真正重要的优化模式
1. 在内存中缓存存储读取
每次SLOAD消耗100-2100 gas。如果多次读取同一个槽,请缓存它。
2. 打包存储变量
将多个变量放在同一个槽中 = 一次SLOAD而非多次。
3. 使用calldata而非memory接收外部参数
4. 短路昂贵的操作
5. 安全时使用unchecked算术
6. 使用自定义错误替代require字符串
7. 最小化calldata中的非零字节
对MEV机器人来说至关重要。
总结
Gas优化不是微优化算术操作码——而是最小化存储访问和外部调用。节省最多gas的模式是架构性的:存储打包、缓存、calldata使用和访问列表优化。