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估算。