solidity-gas-optimization

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Solidity Gas Optimization

Solidity Gas优化

When to Apply

适用场景

  • During contract development to reduce deployment and runtime costs.
  • When hitting the 24KB contract size limit.
  • When optimizing high-frequency functions (e.g., swaps, transfers).
  • When designing storage-heavy protocols.
  • Before final security audits to ensure efficiency doesn't compromise safety.
  • 在合约开发阶段降低部署和运行成本时。
  • 当合约大小达到24KB限制时。
  • 优化高频函数(如交换、转账)时。
  • 设计存储密集型协议时。
  • 最终安全审计前,确保效率不影响安全性时。

Critical Optimizations

关键优化手段

Storage Layout Packing

存储布局打包

Pack variables into 32-byte slots by ordering them by size.
solidity
// BAD: 3 slots
uint128 a; uint256 b; uint128 c;
// GOOD: 2 slots
uint128 a; uint128 c; uint256 b;
按变量大小排序,将变量打包进32字节的存储槽中。
solidity
// BAD: 3 slots
uint128 a; uint256 b; uint128 c;
// GOOD: 2 slots
uint128 a; uint128 c; uint256 b;

Custom Errors vs Revert Strings

自定义错误与回退字符串

Custom errors save gas on deployment and revert execution.
solidity
// BAD: revert("Unauthorized");
// GOOD:
error Unauthorized();
if (msg.sender != owner) revert Unauthorized();
自定义错误可减少部署和回退执行时的Gas消耗。
solidity
// BAD: revert("Unauthorized");
// GOOD:
error Unauthorized();
if (msg.sender != owner) revert Unauthorized();

Immutable and Constant Variables

不可变变量与常量

Use
constant
for values known at compile time,
immutable
for values set in constructor.
solidity
// GOOD: Saves ~20k gas per read vs storage
uint256 public constant FEE = 100;
address public immutable factory;
对于编译时已知的值使用
constant
,对于构造函数中设置的值使用
immutable
solidity
// GOOD: 相比存储读取,每次读取可节省约20k Gas
uint256 public constant FEE = 100;
address public immutable factory;

High Impact Optimizations

高影响优化手段

Calldata vs Memory

Calldata与Memory对比

Use
calldata
for read-only function parameters to avoid copying to memory.
solidity
// BAD: function process(uint[] memory data)
// GOOD: function process(uint[] calldata data)
对于只读函数参数,使用
calldata
避免复制到内存中。
solidity
// BAD: function process(uint[] memory data)
// GOOD: function process(uint[] calldata data)

Unchecked Arithmetic

无检查算术运算

Use
unchecked
for increments in loops where overflow is impossible.
solidity
// GOOD: Saves gas on every iteration
for (uint i = 0; i < len; ) {
    // logic
    unchecked { ++i; }
}
在不可能溢出的循环递增中使用
unchecked
solidity
// GOOD: 每次迭代都能节省Gas
for (uint i = 0; i < len; ) {
    // logic
    unchecked { ++i; }
}

Short-Circuit Evaluation

短路求值

Order
&&
and
||
conditions so the cheapest/most likely to fail/succeed is first.
solidity
// GOOD: cheapCondition() checked first
if (cheapCondition() && expensiveCondition()) { ... }
&&
||
条件排序,将成本最低/最可能失败/成功的条件放在前面。
solidity
// GOOD: 先检查低成本条件
if (cheapCondition() && expensiveCondition()) { ... }

Medium Impact Optimizations

中影响优化手段

Loop Optimizations

循环优化

Cache array length and avoid storage reads inside loops.
solidity
// GOOD: Cache length, use calldata/memory
uint len = arr.length;
for (uint i = 0; i < len; ++i) { ... }
缓存数组长度,避免在循环内读取存储。
solidity
// GOOD: 缓存长度,使用calldata/memory
uint len = arr.length;
for (uint i = 0; i < len; ++i) { ... }

Efficient Data Types

高效数据类型

Use
uint256
for general math (EVM word size). Use
bytes32
instead of
string
for short text.
solidity
// GOOD: bytes32 is cheaper than string
bytes32 public constant NAME = "MyToken";
通用数学运算使用
uint256
(EVM字长)。短文本使用
bytes32
替代
string
solidity
// GOOD: bytes32比string更节省Gas
bytes32 public constant NAME = "MyToken";

Minimize Storage Writes

最小化存储写入

Batch updates and use transient storage (
TSTORE
/
TLOAD
) for same-transaction state.
solidity
// GOOD: EIP-1153 (Solidity >=0.8.24)
assembly { tstore(slot, value) }
批量更新,对同一交易内的状态使用临时存储(
TSTORE
/
TLOAD
)。
solidity
// GOOD: EIP-1153(Solidity >=0.8.24)
assembly { tstore(slot, value) }

Advanced Optimizations

高级优化手段

Assembly (Yul)

汇编(Yul)

Use for fine-grained control over storage and memory. Document heavily.
solidity
// GOOD: Efficient transfer
assembly {
    let success := call(gas(), to, amount, 0, 0, 0, 0)
}
用于对存储和内存进行细粒度控制,需详细注释。
solidity
// GOOD: 高效转账
assembly {
    let success := call(gas(), to, amount, 0, 0, 0, 0)
}

Solady Library

Solady库

Use Solady for highly optimized base contracts and utilities.
solidity
// GOOD: Use Solady's SafeTransferLib
import {SafeTransferLib} from "solady/utils/SafeTransferLib.sol";
SafeTransferLib.safeTransfer(token, to, amount);
使用Solady获取高度优化的基础合约和工具。
solidity
// GOOD: 使用Solady的SafeTransferLib
import {SafeTransferLib} from "solady/utils/SafeTransferLib.sol";
SafeTransferLib.safeTransfer(token, to, amount);

EIP-1167 Minimal Proxy

EIP-1167极简代理

Use the "Clone" pattern to deploy many instances of a contract cheaply.
solidity
// GOOD: Deploy proxy instead of full contract
address instance = LibClone.clone(implementation);
使用“克隆”模式低成本部署多个合约实例。
solidity
// GOOD: 部署代理而非完整合约
address instance = LibClone.clone(implementation);

Optimization Checklist

优化检查清单

  1. Are variables packed into 32-byte slots?
  2. Are all revert strings replaced with custom errors?
  3. Are
    constant
    and
    immutable
    used where possible?
  4. Are function parameters
    calldata
    instead of
    memory
    ?
  5. Are loop increments
    unchecked
    ?
  6. Is array length cached before loops?
  7. Are
    uint256
    used instead of smaller types for math?
  8. Are
    bytes32
    used instead of
    string
    for short data?
  9. Are storage writes minimized/batched?
  10. Is
    short-circuiting
    applied to complex conditionals?
  11. Are
    external
    functions used instead of
    public
    where possible?
  12. Is
    Solady
    used for standard utilities?
  13. Are
    TSTORE
    /
    TLOAD
    used for transient state?
  14. Is the contract size within the 24KB limit?
  1. 变量是否已打包进32字节存储槽?
  2. 所有回退字符串是否已替换为自定义错误?
  3. 是否在合适的地方使用了
    constant
    immutable
  4. 函数参数是否使用
    calldata
    而非
    memory
  5. 循环递增是否使用了
    unchecked
  6. 数组长度是否在循环前缓存?
  7. 数学运算是否使用
    uint256
    而非更小的类型?
  8. 短数据是否使用
    bytes32
    而非
    string
  9. 存储写入是否已最小化/批量处理?
  10. 复杂条件是否应用了短路求值?
  11. 是否在合适的地方使用
    external
    函数而非
    public
  12. 是否使用Solady实现标准工具?
  13. 临时状态是否使用了
    TSTORE
    /
    TLOAD
  14. 合约大小是否在24KB限制内?

Enhanced with MCP

结合MCP增强优化

Leverage
solidity-agent-toolkit
tools for precise optimization:
  • gas_snapshot
    : Compare gas usage across different implementations.
  • inspect_storage
    : Visualize storage layout and identify packing opportunities.
  • estimate_gas
    : Get real-time gas estimates for specific function calls.
利用
solidity-agent-toolkit
工具实现精准优化:
  • gas_snapshot
    :对比不同实现的Gas消耗。
  • inspect_storage
    :可视化存储布局,识别打包机会。
  • estimate_gas
    :获取特定函数调用的实时Gas估算。