Gate Smart Contract Toolkit
🛠️ Gate 智能合约工具集 - 字节码检查、合约升级验证
功能特性
🔍 字节码检查(check)
- ✅ 检查链下合约代码和链上合约代码是否一致
- ✅ 支持检查单个合约、指定网络或所有合约
- ✅ 智能识别 Constructor 参数差异和 Immutable 变量差异
- ✅ 自动移除元数据进行比较
- ✅ 生成详细的 JSON 报告
- ✅ 支持增量更新报告
🔄 合约状态同步(sync)
- ✅ 同步链上合约状态到本地 .openzeppelin 文件
- ✅ 自动读取链上实现合约地址
- ✅ 获取并更新存储布局信息
- ✅ 适用于多签钱包升级后的状态同步
✅ 升级验证(validate)
- ✅ 验证合约升级的安全性
- ✅ 检查存储布局兼容性
- ✅ 自动部署新实现合约
- ✅ 生成 upgradeToAndCall 的 calldata
- ✅ 支持同一合约和不同合约的升级模式
一、发布 NPM 包
1. 准备发布
cd evm-checkcode-cli
npm install
npm run build
2. 配置 NPM 账户
npm login
3. 发布到 NPM
npm pack --dry-run
npm publish
npm publish --access public
4. 更新版本
npm version patch
npm version minor
npm version major
npm publish
二、使用 NPM 包
1. 安装
在你的 Hardhat 项目中安装:
npm install --save-dev gate-evm-check-code
或全局安装:
npm install -g gate-evm-check-code
安装所需的 peer dependencies:
npm install --save-dev hardhat ethers @openzeppelin/hardhat-upgrades @openzeppelin/upgrades-core
2. 创建配置文件
在项目根目录创建 contractInfo.json 文件:
{
"eth": {
"Vault": "0x80aaf2e4636c510e067a5d300d8bafd48027addf",
"VaultCrossChainRelay": "0x060194eec4556096baaabd6bf553d2658d6a66ab"
},
"bsc": {
"Vault": "0x2cb7d2603a5f43b9fe79e98f09fe3eec40b6765d",
"VaultCrossChainRelay": "0x23ae3a565e0896866e7725fe6d49fd777359c162"
}
}
格式说明:
- 第一层 key 是网络名称(必须与
hardhat.config.js 中的网络名称一致)
- 第二层 key 是合约名称(必须与编译的合约名称一致)
- value 是合约地址
3. 配置 Hardhat
确保 hardhat.config.js 中配置了相应的网络:
module.exports = {
networks: {
eth: {
url: "https://eth-mainnet.g.alchemy.com/v2/YOUR-API-KEY",
},
bsc: {
url: "https://bsc-dataseed.binance.org/",
}
}
};
4. 编译合约
npx hardhat compile
5. 使用工具
📋 查看帮助
npx gate-tool --help
🔍 字节码检查
npx gate-tool check
npx gate-tool check --contract Vault
npx gate-tool check --network eth
npx gate-tool check --config ./config/contracts.json
npx gate-tool check --output ./reports/result.json
🔄 同步链上合约状态
当合约通过 calldata 方式由其他人(如多签钱包)执行升级后,本地的 .openzeppelin 文件不会自动更新。使用此命令可以从链上读取最新状态并更新本地文件。
npx gate-tool sync \
--proxy 0x1234... \
--contract CounterUUPS \
--network sepolia
npx gate-tool sync \
--proxy 0x1234... \
--contract CounterUUPS
✅ 验证升级安全性并生成 calldata
验证合约升级的安全性,并生成 upgradeToAndCall 的 calldata,用于多签钱包执行升级。
npx gate-tool validate \
--proxy 0x1234... \
--old CounterUUPS \
--new CounterUUPSV2 \
--network sepolia
npx gate-tool validate \
--proxy 0x1234... \
--old CounterUUPS \
--new CounterUUPS \
--network sepolia
npx gate-tool validate \
--proxy 0x1234... \
--old CounterUUPS \
--new CounterUUPSV2 \
--network sepolia \
--output ./upgrade-info.json
注意: validate 命令会在链上部署新的实现合约(仅用于验证),但不会升级代理合约。请使用生成的 calldata 通过多签钱包执行升级。
6. 命令选项
check 命令
--contract <name> | -c | 指定要检查的合约名称 | - |
--network <name> | -n | 指定要检查的网络名称 | - |
--config <path> | - | 指定配置文件路径 | ./contractInfo.json |
--output <path> | -o | 指定输出报告文件路径 | ./bytecode-check-report.json |
sync 命令
--proxy <address> | - | 代理合约地址 | ✅ |
--contract <name> | - | 合约名称 | ✅ |
--network <name> | -n | 网络名称 | - |
validate 命令
--proxy <address> | - | 代理合约地址 | ✅ |
--old <name> | - | 旧合约名称 | ✅ |
--new <name> | - | 新合约名称 | ✅ |
--network <name> | -n | 网络名称 | - |
--output <path> | -o | 输出文件路径 | ./upgradeCalldata.json |
三、输出示例
✓ 已加载配置文件: /path/to/contractInfo.json
配置文件: /path/to/contractInfo.json
网络数量: 2
- eth: 2 个合约
- bsc: 2 个合约
ℹ 检查所有合约...
✓ 检查完成,共 4 个合约
================================================================================
字节码检查报告
================================================================================
总计检查: 4
✓ 匹配: 4
✗ 不匹配: 0
⚠ 错误: 0
✅ 匹配的合约:
--------------------------------------------------------------------------------
Vault (eth): 完全匹配
VaultCrossChainRelay (eth): Constructor参数差异
Vault (bsc): 完全匹配
VaultCrossChainRelay (bsc): 完全匹配
✓ 报告已保存: /path/to/bytecode-check-report.json
四、报告文件格式
生成的 bytecode-check-report.json 文件格式:
{
"eth": {
"Vault": {
"contract": "Vault",
"address": "0x80aaf2e4636c510e067a5d300d8bafd48027addf",
"matches": true,
"error": null,
"reason": "完全匹配",
"onChainBytecodeLength": 12345,
"localBytecodeLength": 12345
}
},
"bsc": {
"Vault": {
"contract": "Vault",
"address": "0x2cb7d2603a5f43b9fe79e98f09fe3eec40b6765d",
"matches": true,
"error": null,
"reason": "完全匹配",
"onChainBytecodeLength": 12345,
"localBytecodeLength": 12345
}
}
}
五、完整工作流程示例
场景:通过多签钱包升级 UUPS 合约
Step 1: 修改合约代码
修改你的合约文件(例如 contracts/CounterUUPS.sol),添加新功能或修复 bug。
Step 2: 验证升级安全性并生成 calldata
npx gate-tool validate \
--proxy 0x1234567890abcdef... \
--old CounterUUPS \
--new CounterUUPS \
--network sepolia
这个命令会:
- 清理并编译合约
- 部署新的实现合约
- 验证存储布局兼容性
- 生成
upgradeCalldata.json 文件
Step 3: 通过多签钱包执行升级
使用生成的 calldata 在多签钱包(如 Gnosis Safe)中创建交易:
- Target: 代理合约地址(在输出中显示)
- Calldata: 从
upgradeCalldata.json 中复制
Step 4: 同步本地状态
升级完成后,同步链上状态到本地:
npx gate-tool sync \
--proxy 0x1234567890abcdef... \
--contract CounterUUPS \
--network sepolia
这会更新你本地的 .openzeppelin/sepolia.json 文件,确保下次升级时有正确的参考。
Step 5: 验证字节码
确认链上合约代码与本地一致:
npx gate-tool check --network sepolia --contract CounterUUPS
六、常见问题
Q: 提示找不到配置文件怎么办?
A: 确保在项目根目录创建了 contractInfo.json 文件,或使用 --config 参数指定路径。
Q: 提示不是 Hardhat 项目怎么办?
A: 确保在 Hardhat 项目根目录下运行命令,并且存在 hardhat.config.js 或 hardhat.config.ts 文件。
Q: 如何处理 Constructor 参数差异?
A: Constructor 参数差异是正常的,工具会智能识别并标记为"匹配"。
Q: sync 命令什么时候使用?
A: 当合约通过 calldata 方式由其他人执行升级时(如通过多签钱包),本地的 .openzeppelin 文件不会自动更新。使用 sync 命令可以从链上读取最新状态并更新本地文件。
Q: validate 命令会实际升级合约吗?
A: 不会。validate 命令只会部署新的实现合约并生成 calldata,不会执行实际的升级操作。你需要使用生成的 calldata 通过多签钱包或其他方式手动执行升级。
Q: 如何在 CI/CD 中使用?
A: 可以在 CI/CD 流程中添加 npx gate-tool check 命令,确保每次部署前验证合约代码一致性。
Q: 支持哪些代理模式?
A: 目前支持 UUPS(Universal Upgradeable Proxy Standard)代理模式。其他代理模式(如 Transparent Proxy)的支持正在开发中。
许可证
MIT
更新日志
v2.0.0
- ✨ 新增
sync 命令:同步链上合约状态到本地
- ✨ 新增
validate 命令:验证升级安全性并生成 calldata
- 🎨 命令行工具更名为
gate-tool(保留 bytecode-check 向后兼容)
- 📝 完善文档和使用示例
- 🔧 优化错误提示和用户体验
v1.0.0
作者
kiro
贡献
欢迎提交 Issue 和 Pull Request!
相关链接