Gas 优化大师课编译器优化编译器优化器设置

编译器优化器设置

Solidity 编译器不仅仅是将代码转换为字节码的工具,它更是在追求 Gas 效率过程中的强大盟友。正确配置编译器是编写优化智能合约的基础步骤。

分析

  1. 始终使用最新的编译器版本

    在 Gas 优化方面,你的第一道防线就是使用最新的 Solidity 编译器。新版本通常包含重大的改进。

  • 如何指定版本: 在合约文件的顶部声明一个较新的版本。使用 ^ 的浮动 pragma可以确保你的合约能受益于最新的补丁版本,这些版本通常包含错误修复和微小的优化。
// 此合约与 0.8.30 及之后的所有补丁版本兼容
pragma solidity ^0.8.30;
  • 核心优势:

    • 节省 Gas: 新版编译器集成了更复杂的优化程序,可以显著降低部署和运行时的 Gas 成本。

    • 增强的安全性: 引入了额外的安全检查和新功能,例如自定义错误(revert CustomError();),它比基于字符串的 revert 消息更节省 Gas。

    • 新功能: 可以使用最新的语言特性和功能。

  • 重要注意事项:

    • 向后兼容性: 升级时,请确保你的合约不依赖于旧版本编译器的特定行为。

    • 外部库: 确认所有引用的库和接口都与你选择的编译器版本兼容。

    • 彻底测试: 升级编译器后,务必运行完整的测试套件,以捕捉任何意外行为或功能回归。

  1. 启用并配置优化器

Solidity 优化器通过简化复杂表达式和优化汇编代码来降低 Gas 成本。这是一个至关重要的工具,但需要理解一个由 optimizer-runs参数控制的关键权衡。

  • optimizer-runs 的权衡:

这个参数用于告知编译器,你预计在合约的整个生命周期中调用其函数的次数。它平衡了两种成本:

  1. 部署成本: 将合约字节码部署到区块链的成本。

  2. 执行成本: 用户与合约交互时,执行其函数的成本。

  • 如何选择 runs 的值:

    • runs 值 (例如 200): 编译器优先考虑降低部署成本。它会生成更小的创建字节码,但最终的运行时代码可能效率较低。

      • 最适用于: 调用频率不高的合约。
    • runs 值 (例如 10000):

    编译器优先考虑降低执行成本。它可能会生成更大的创建字节码,但运行时代码经过高度优化,函数调用成本更低。

    • 最适用于: 调用非常频繁的合约。从长远来看,执行成本上节省的 Gas 将远远超过初始部署时略高的成本。
  • 如何配置 (以 foundry.toml 为例):

大多数开发框架都允许你在配置文件中设置这些参数。

[profile.default]
optimizer = true
optimizer_runs = 10000

测试

总结

  • 保持更新: 使用与项目依赖兼容的、尽可能新的 Solidity 编译器版本。

  • 启用优化器: 编译生产环境的合约时,务必启用优化器。

  • 调整 runs 参数: 根据合约的预期使用频率来设置 —optimizer-runs 的值。对于大多数高流量的协议,设置一个较大的值是正确的选择。

  • 严格测试: 在更改编译器版本或优化器设置后,运行完整的测试套件(包括 Gas 审计测试),以验证其正确性并衡量对 Gas 成本的影响。

对应源码

本文配套代码固定到提交 8960383;Gas 数据会随编译器、优化器参数和 EVM 版本变化。