You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Solidity ConstantOptimiser优化疑问:为何分解address(0xAAAA)而非直接推送?

Solidity常量优化的Gas疑惑

我在Remix IDE中开启optimize=true调试时,发现Solidity代码address(0xAAAA)生成了以下opcode,实际是在计算20字节的1:

PUSH1 0x1
PUSH1 0x1
PUSH1 0xa0
SHL
SUB

我在Solidity仓库的ConstantOptimiser.cpp文件中找到findRepresentation方法,它会分解大于255的常量。这种方式消耗的gas难道不比直接推送常量更多吗?为何要执行该优化?


核心原因:优先优化部署字节码成本

这种优化的本质是牺牲少量运行时Gas,换取部署时的字节码大小成本节省,而后者在很多场景下收益更高:

1. 字节码长度的部署成本差异

  • 直接推送20字节的常量(比如0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)需要用PUSH20指令,对应的字节码总长度是21字节(1字节的PUSH20操作码 + 20字节的常量值),部署时每字节收费200Gas,总成本是21 × 200 = 4200 Gas。
  • 而生成的计算式opcode总长度仅8字节:3个PUSH1(每个2字节) + SHL(1字节) + SUB(1字节),部署成本是8 × 200 = 1600 Gas,直接节省2600 Gas的部署成本。

2. 运行时Gas的权衡

运行时的Gas消耗确实会增加:

  • 直接推送的PUSH20仅消耗3 Gas;
  • 计算式的5条指令总共消耗3×3 + 3 + 3 = 15 Gas。

但优化器的逻辑是:部署成本是一次性的固定支出,而运行时Gas只有在合约被调用时才会产生。如果合约不是高频调用该常量,或者部署次数远多于调用次数(比如工厂合约批量创建子合约),这种优化的整体收益是正的。

3. 优化器的决策逻辑

Solidity的ConstantOptimiser会针对不同常量的大小、使用频率等维度做权衡:

  • 对于小常量(≤255),直接用PUSH1推送更高效;
  • 对于大常量,若使用次数少,优先用计算式压缩字节码;若使用次数多,则可能将常量存入合约存储或内存,避免重复计算。

内容的提问来源于stack exchange,提问作者Zoey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 12:32:53