
在2021年,Uniswap上高峰期兑换代币的Gas费用可能超过100美元。铸造一个NFT需要50到200美元。提供流动性可能会花费150到300美元。对于许多用户来说,Gas费用比交易本身的价值还高。这时,Gas优化从“一种附加”变成了“生存必需”。
Gas优化是一门让智能合约更便宜的艺术和科学,即用最少的计算获取最多的功能。开发者在这个过程中发现了一些巧妙且偶尔令人惊叹的节省Gas技巧。因为在区块链开发中,浪费直接意味着用户的金钱损失。
基本原理很简单:并非所有操作的成本都是一样的。存储操作非常昂贵——第一次写入存储需要20,000 Gas,后续的写入需要5,000 Gas。从冷存储读取则需2,100 Gas。而基本计算(如加法或乘法)只需3到10 Gas。显而易见,存储昂贵,计算便宜。大多数的Gas优化都围绕着减少存储操作进行。
让我们谈谈存储打包,这是最大收益的地方。EVM将数据存储在32字节的槽中。如果空间浪费了,gas就会被浪费。一个天真的实现可能使用三个独立的uint256变量,占用三个完整的存储槽,需花费约60,000 Gas来写入。但如果你巧妙地打包这些变量——如使用uint128、uint64和uint64——它们就可以全部放在一个槽中,将成本降至20,000 Gas。通过理解EVM如何组织数据,这就是节省40,000 Gas的方法。
你能更积极地打包。一个地址占用160位,而直到公元8921年的时间戳占用48位。将一个地址、一个时间戳和一个数量打包到一个256位的槽中,你已经将三条数据合并到一个存储操作中了。代价是需要增加计算来打包和解包这些值,但由于计算便宜,存储昂贵,这种权衡几乎总是值得的。
位图技术更进一步用于追踪布尔状态。在映射中存储布尔需要每个布尔一个存储槽——追踪100个声明大约需要200万个Gas。但用位图,你可以使用按位操作将256个布尔打包到一个存储槽中。追踪相同的100个声明将降至大约20,000 Gas。这是100倍的改善。Uniswap V3、OpenSea和主要协议广泛使用位图技术,因为节省实在太大了不容忽视。
有时候你根本不需要存储。你能推导出值,而不是存储它们吗?存储一个倍增的供应值意味着每次供应变更都要额外写入存储。按需计算几乎不需要什么成本。事件提供了另一种选择——如果你需要历史记录但不需要链上查询,发出事件而不是存储数据。事件根据索引主题的不同,费用从375到1,500 Gas不等。存储写入费用则需20,000+ Gas。这是一种10到20倍的节省,代价是事件不能在链上查询,需要链下索引。
EVM从左到右评估条件并在结果确定时短路。将便宜的检查放在前面——如果它们失败,昂贵的操作就不会运行。这看起来显而易见,但常常被遗忘。外部调用也很昂贵,尤其是对冷地址的调用。尽可能批量处理。与其进行100次单独的代币转账,不如实施批量操作。许多ERC-20代币现在专为Gas优化提供了批量功能。
对于函数参数,总是尽可能使用calldata而不是memory。memory会从calldata复制数据,这样很耗Gas。直接从calldata读取更便宜——通常根据数组大小节省100到1,000+ Gas。Solidity 0.8+增加了自动溢出检查,这些检查安全但费用昂贵。当你确定不会发生溢出时,如在递增循环计数器时,小心使用unchecked块。这个操作可以从约30 Gas降至3 Gas。
积极缓存存储读取。三次读取相同的存储变量需要6,300 Gas。读取一次并缓存到一个memory变量中只需2,100 Gas。这种模式在优化代码中无处不在——从存储中读取一次,并使用缓存值。虽然EIP-3529之后退款不如以前慷慨,但是删除未使用的存储依然能给予Gas退款。
开发者找到了愈加创意的Gas节省方法。Solidity 0.8.4引入的自定义错误相比字符串错误信息大幅节省了成本——将发生错误的费用减少了一半。内联汇编绕过Solidity的安全检查,以更低级别的方式控制EVM,被像Uniswap V3和Seaport这样复杂的协议使用。Seaport通过按位操作将多个订单参数打包到单个存储槽中——这既美丽又可怕。
对于空投,Merkle树完全消除了存储资格映射的需求。用户提供他们在树中的证明,资格存储为零,仅需因每次声明消耗一个布尔。Uniswap的Merkle Distributor使用这种技术节省了数百万Gas。代码复杂性大大增加,但当你要向数千用户分发时,节省是值得的。
但Gas优化可能效果适得其反。高度优化的代码往往难以阅读。位图、打包存储以及汇编使代码难以理解和审核。当你用打包的uint256值存储余额,需要自定义函数来编码和解码时,你已经为了效率而牺牲了可读性。复杂性增加了安全隐患——优化引入了错误,而金融合同中的错误就意味着金钱损失。1500万美元的Parity钱包冻结,部分原因就在于复杂的优化。
过早优化的确存在。许多项目在拥有用户之前过度优化。首先专注于安全性和功能。当Gas成本真正重要时再优化——当用户抱怨、当你的合约受到大量使用、当竞争对手提供更低的成本、或在高Gas时期部署时。不要过早优化实验性或低流量合约,尤其是在安全审计完成之前。除非你已经分析过且非常清楚瓶颈所在,否则不要显著牺牲可读性。
使用Hardhat Gas Reporter或Foundry的Gas跟踪工具进行优化前的分析。测量、识别费用高的操作,然后具体优化那些操作。Slither通过静态分析识别低效之处。这些工具让优化变得系统化而不是凭猜测。
讽刺的是,当开发者掌握了Gas优化时,二层rollup让优化变得不再那么关键。在Optimism、Arbitrum、Base和zkSync上,交易Gas成本比以太坊主网络降低了90%到95%。在主网上花费10美元的兑换在L2上只需0.10到0.50美元。那么这是否意味着Gas优化无所谓了?
不完全是。合约部署成本仍随着字节码大小而增长——即使在L2上,较小的合约部署成本也更低。即使Gas价格更低,存储操作仍然相对昂贵,因此良好的实践仍然适用。核心基础设施通常留在主网上,那里的Gas仍然重要。学习高效代码让你成为一名更好的开发人员,无论Gas价格如何。但L2确实降低了压力。2021年每1,000 Gas都很重要。在2025年,优化更多是关于良好工程而非生存。
Gas优化创造了区块链开发中的独特激励。由于合约是公开的,开发者相互学习对方的技巧。Gas效率更高的协议获得更多用户——Seaport的建立就是为了在Gas成本上击败竞争对手的市场。Gas限制迫使产生了许多原本不会存在的创意解决方案。
痴迷于节省500 Gas值得吗?当Gas价格是0.0001美元时,也许不值得。当其为0.10美元时,或许值得。当这种节省适用于数百万笔交易时,绝对值得。Gas优化部分是工程,部分是经济学,部分则是痴迷的解谜。它是区块链开发者最能直接影响用户体验的方式之一。
在这个有时感觉与现实脱节的领域中,优化一些具体和可测量的东西是一种清新的体验。你可以测试两种实现,精准看到哪种成本更低。你能部署一个优化,精确计算你为用户节省了多少。当你通过巧妙的优化把交易成本降低5美元,这是真实的影响,用户会立刻感受到。
这很重要。在区块链中,降低成本不仅仅是良好的工程——这是让科技为更多人所用。每一个Gas优化的合约都是使加密货币更加贴近普通人及其预算的一小步。那些在单个存储槽中打包变量并使用位图技巧的痴迷开发者,不仅仅是在炫耀他们的技术技能。他们正在实际让未来的去中心化系统可行。
注意: Gas成本和优化技术随着Solidity版本和EVM更新而演变。始终彻底测试优化,并在Gas节省和安全性之间优先考虑安全性。本文反映2025年的实践,仅用于教育目的。