mcpField
S
solidity-gas-optimization

solidity-gas-optimization

github.com/pseudoyu开发4570 次安装24 周前更新
代码仓库

关于 solidity-gas-optimization

面向智能合约开发者和审查者的 Solidity Gas 优化参考,按影响和风险整理八类技巧,并说明不安全及过时模式的注意事项。

主要功能

  1. 01涵盖八类优化技巧
  2. 02按影响和风险排序
  3. 03存储、部署与 calldata 技巧
  4. 04编译器与汇编模式
  5. 05不安全或过时做法警示
  6. 06基准测试与可读性指导

适用场景

  1. 01降低合约部署或执行成本
  2. 02审查合约中的 Gas 优化机会
  3. 03比较存储布局或设计选择
  4. 04评估底层优化技巧的风险

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/pseudoyu/agent-skills --skill solidity-gas-optimization

安装后在 Claude Code 中输入/solidity-gas-optimization确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
solidity-gas-guidelines.md
references/rules/
assembly-01-basics.md
calldata-01-memory-vs-calldata.md
compiler-01-loops.md
compiler-02-math.md
crosscall-01-multicall.md
deploy-01-custom-errors.md
deploy-02-clones-proxies.md
design-01-token-standards.md
design-02-signatures-vs-merkle.md
storage-01-zero-to-one.md
storage-02-cache-variables.md
storage-03-packing.md
storage-04-constants-immutables.md

详细介绍

Solidity Gas 优化

概述

全面的 Solidity 智能合约 Gas 优化指南,涵盖 8 个类别中的 80 多种技巧。基于 RareSkills Book of Gas Optimization。规则按影响和安全性排序。

适用场景

在以下情况下参考这些指南:

  • 编写新的 Solidity 智能合约
  • 审查或审计现有合约
  • 优化部署或执行的 Gas 成本
  • 重构合约存储布局
  • 实现跨合约交互
  • 在设计模式之间进行选择(ERC721 与 ERC1155 等)

按优先级排序的类别

优先级类别影响风险
1存储优化严重低
2部署优化高低
3Calldata 优化高低
4设计模式高中
5跨合约调用中高中
6编译器优化中低
7Assembly 技巧中高
8危险技巧低严重

快速参考

严重:存储优化(优先应用)

从零到非零的写入:

  • 避免向存储中写入从零变为非零的值(耗费 22,100 Gas)
  • 对类似布尔值的数据使用 1/2,而非 0/1
  • 在 ERC20 合约中保留最低余额

变量打包:

// Bad: 3 slots
struct Unpacked {
    uint64 time;      // slot 1
    uint256 amount;   // slot 2
    address user;     // slot 3
}

// Good: 2 slots
struct Packed {
    uint64 time;      // slot 1 (with address)
    address user;     // slot 1
    uint256 amount;   // slot 2
}

缓存:

// Bad: reads storage twice
function increment() public {
    require(count < 10);
    count = count + 1;
}

// Good: reads storage once
function increment() public {
    uint256 _count = count;
    require(_count < 10);
    count = _count + 1;
}

常量与不可变量:

uint256 constant MAX = 100;        // No storage slot
address immutable owner;           // Set in constructor, no storage
高:部署优化

自定义错误:

// Bad: ~64+ bytes
require(amount <= limit, "Amount exceeds limit");

// Good: ~4 bytes
error ExceedsLimit();
if (amount > limit) revert ExceedsLimit();

可支付构造函数:

// Saves ~200 gas on deployment
constructor() payable {}

克隆模式:

  • 对重复部署使用 EIP-1167 最小代理
  • 对可升级合约,优先选择 UUPS,而非 Transparent Proxy
高:Calldata 优化

Calldata 与 Memory:

// Bad: copies to memory
function process(bytes memory data) external {}

// Good: reads directly from calldata
function process(bytes calldata data) external {}

避免使用有符号整数:

  • 小的负数开销较高(例如,-1 = 0xffff...)
  • 在函数参数中使用无符号整数
高:设计模式

代币标准:

  • 对 NFT 优先选择 ERC1155,而非 ERC721(没有 balanceOf 开销)
  • 考虑将多个 ERC20 合并为一个 ERC1155

签名与 Merkle:

  • 对白名单优先选择 ECDSA 签名,而非 Merkle 树
  • 实现 ERC20Permit,以便在一个 tx 中完成 approve 和 transfer

替代库:

  • 为提高 Gas 效率,考虑使用 Solmate/Solady,而非 OpenZeppelin
中高:跨合约调用

减少交互:

  • 使用 ERC1363 transferAndCall,而非 approve + transferFrom
  • 实现 multicall 以批量处理操作
  • 缓存外部调用结果(例如 Chainlink 预言机)

访问列表:

  • 使用 ERC2930 访问列表交易预热存储
中:编译器优化

循环模式:

// Good: unchecked increment, cached length
uint256 len = arr.length;
for (uint256 i; i < len; ) {
    // logic
    unchecked { ++i; }
}

命名返回值:

// More efficient bytecode
function calc(uint256 x) pure returns (uint256 result) {
    result = x * 2;
}

位移:

// Cheaper: 3 gas
x << 1   // x * 2
x >> 2   // x / 4

// Expensive: 5 gas
x * 2
x / 4

短路布尔表达式:

  • 在 && 中将最可能失败的条件放在前面
  • 在 || 中将最可能成功的条件放在前面
中:Assembly(谨慎使用)

高效检查:

// Check address(0) with assembly
assembly {
    if iszero(caller()) { revert(0, 0) }
}

// Even/odd check
x & 1  // instead of x % 2

内存复用:

  • 对小型操作复用暂存空间(0x00-0x40)
  • 避免在循环中扩展内存
避免:危险技巧

这些做法不适合用于生产环境:

  • 将所有函数设为 payable
  • 忽略 send() 的返回值
  • 使用 gasleft() 进行分支判断
  • 在测试中操纵 block.number

已过时的模式

这些模式不再适用于现代 Solidity:

  • “external 比 public 便宜”——不再成立
  • “!= 0 比 > 0 便宜”——在 0.8.12 左右已发生变化

参考资料

包含代码示例的完整文档:

  • references/solidity-gas-guidelines.md - 完整指南
  • references/rules/ - 按类别整理的单项模式

查找特定模式:

grep -l "storage" references/rules/
grep -l "assembly" references/rules/
grep -l "struct" references/rules/

references/rules/ 中的规则类别

  • storage-* - 存储优化模式
  • deploy-* - 部署 Gas 节省技巧
  • calldata-* - Calldata 优化
  • design-* - 设计模式选择
  • crosscall-* - 跨合约调用优化
  • compiler-* - 编译器优化模式
  • assembly-* - 底层 Assembly 技巧

核心原则

  1. 始终进行基准测试 - 编译器行为会因上下文和版本而异
  2. 兼顾可读性 - 并非所有优化都值得增加代码复杂度
  3. 两种方案都要测试 - 违反直觉的优化有时反而会增加开销
  4. 考虑使用 --via-ir - 现代编译器选项可能会使某些技巧过时
  5. 使用替代库 - 在 Gas 方面,Solmate/Solady 往往优于 OpenZeppelin

评论

支持 Markdown