gate-evm-tools
v1.0.28
Published
Gate 智能合约工具集 - 字节码检查、合约升级验证、合约状态同步
Maintainers
Readme
Gate Smart Contract Tools
🛠️ Gate 智能合约工具集 - EVM/zkSync CREATE2 与 UUPS 计划、字节码检查、升级验证、合约状态同步
功能特性
🔧 配置修复(fix)
- ✅ 自动检测 Hardhat 配置文件的兼容性问题
- ✅ 智能修复 ESM 模块导入错误
- ✅ 交互式确认修复操作
- ✅ 自动备份原配置文件
- ✅ 支持仅检查模式
🔍 字节码检查(check)
- ✅ 检查链下合约代码和链上合约代码是否一致
- ✅ 支持检查单个合约、指定网络或所有合约
- ✅ 自动检测可升级合约(ERC1967代理),获取实现合约地址进行比对
- ✅ 智能识别 Constructor 参数差异和 Immutable 变量差异
- ✅ 自动移除元数据进行比较
- ✅ 生成详细的 JSON 报告
- ✅ 支持增量更新报告
- ✅ 检测到配置错误时提供自动修复选项
🔄 合约状态同步(sync)
- ✅ 同步链上合约状态到本地 .openzeppelin 文件
- ✅ 自动读取链上实现合约地址
- ✅ 获取并更新存储布局信息
- ✅ EVM 与 zkSync 按 target 配置路由 manifest,并以事务方式写入或完整回滚
🧭 规范化部署准备(prepare)
- ✅ 普通 CREATE2、UUPS 初始部署和 UUPS 升级共用一个 version 1 plan contract
- ✅ EVM 缺省兼容;zkSync 使用 zksolc artifact、EraVM bytecode hash、ContractDeployer calldata 与
factoryDeps - ✅ OpenZeppelin / Matter Labs 实现安全性和存储布局校验发生在任何签名或广播之前
- ✅ prepare-only:不签名、不广播、不写 manifest
✅ 兼容升级验证(validate,legacy)
- ✅ 自动检测合约类型(代理合约 or 实现合约)
- ✅ 代理模式:验证升级安全性并生成 upgradeCalldata
- ✅ 实现模式:验证存储布局兼容性并部署新合约
- ✅ 支持通过工厂合约 Create2 部署新实现(可选 salt)
- ✅ 检查存储布局兼容性
- ✅ 自动部署新实现合约
- ✅ 生成 upgradeToAndCall 的 calldata
- ✅ 支持同一合约和不同合约的升级模式
- ✅ 支持带构造函数参数的合约
EVM/zkSync 统一工作流边界
gate-evm-tools/workflow 是生成工作流唯一的部署准备实现:
- GateTool 读取严格 artifact,执行 OpenZeppelin 校验,计算 CREATE2 地址,并生成 Factory、
upgradeToAndCallcalldata 与 zkSyncfactoryDeps。 - full-template runtime 负责权限、controlled Multicall、immutable execution plan、签名、广播与 receipt reconciliation。
- SmartFlow 校验 immutable plan、receipt 和 finalized UUPS 的
gateToolSync证据,不重新计算 CREATE2 或 calldata。
生成工作流应在当前 Hardhat HRE 内调用:
import { prepareWorkflow } from "gate-evm-tools/workflow";
const plan = await prepareWorkflow(hre, request);人工文件入口使用同一实现:
npx gate-tool prepare \
--network <hardhat-network> \
--request scripts/tasks/<task-id>/gate-tool-request.json \
--output scripts/tasks/<task-id>/gate-tool-plan.jsonrequest 的 kind 只能是 create2-deploy、uups-placeholder-deploy 或 uups-upgrade;scheme 缺省为 evm,也可显式设置为 zksync-eravm。EVM plan 不携带 factoryDeps;每笔 zkSync transaction 都必须显式携带锁定的 factoryDeps,非 bytecode-publishing 交易使用空数组。
📋 Calldata 解析(parse)
- ✅ 解析 EVM calldata,显示函数名称和参数
- ✅ 支持从 Hardhat artifacts 自动查找 ABI
- ✅ 支持指定自定义 ABI 文件路径
- ✅ 支持直接提供 ABI 数组
- ✅ 支持批量解析多个 calldata
- ✅ 友好的彩色输出和 JSON 导出
一、发布 NPM 包
1. 准备发布
# 进入项目目录
cd evm-checkcode-cli
# 安装依赖
npm install
# 编译 TypeScript
npm run build2. 配置 NPM 账户
# 登录 NPM(如果还未登录)
npm login
# 输入用户名、密码、邮箱3. 发布到 NPM
# 检查包信息
npm pack --dry-run
# 发布包
npm publish
# 如果包名已被占用,可以发布到作用域下
# 先修改 package.json 中的 name 为 "@your-username/bytecode-checker-cli"
# 然后执行:
npm publish --access public4. 更新版本
# 更新补丁版本(1.0.0 -> 1.0.1)
npm version patch
# 更新小版本(1.0.0 -> 1.1.0)
npm version minor
# 更新大版本(1.0.0 -> 2.0.0)
npm version major
# 发布新版本
npm publish二、使用 NPM 包
1. 安装
在你的 Hardhat 项目中安装:
npm install --save-dev gate-evm-tools或全局安装:
npm install -g gate-evm-tools2. 创建配置文件
在项目根目录创建 contractInfo.json 文件:
{
"eth": {
"Vault": "0x80aaf2e4636c510e067a5d300d8bafd48027addf",
"VaultCrossChainRelay": "0x060194eec4556096baaabd6bf553d2658d6a66ab"
},
"bsc": {
"Vault": "0x2cb7d2603a5f43b9fe79e98f09fe3eec40b6765d",
"VaultCrossChainRelay": "0x23ae3a565e0896866e7725fe6d49fd777359c162"
}
}格式说明:
- 第一层 key 是网络名称(必须与
hardhat.config.js中的网络名称一致) - 第二层 key 是合约名称(必须与编译的合约名称一致)
- value 是合约地址(可以是代理合约地址,工具会自动检测并获取实现合约地址)
支持可升级合约: 如果配置中的地址是 ERC1967 代理合约,工具会自动:
- 检测该地址是否为代理合约
- 读取实现合约地址(从 ERC1967 存储槽)
- 使用实现合约地址进行字节码比对
这意味着你可以直接在配置文件中填写代理合约地址,无需手动查找实现合约地址。
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/",
}
}
};托管钱包 Signer(ethers v5 / v6)
gate-evm-tools 支持把真实私钥和托管钱包统一放在同一个配置项中:
# 真实私钥
PRIVATE_KEY=0x...
# 或托管钱包凭证
PRIVATE_KEY=custody:<ProjectSecret>:<WalletAddress>
CUSTODY_API_BASE_URL=https://custody.example.comCUSTODY_API_BASE_URL must be an HTTP(S) base URL without embedded
credentials, query parameters, or fragments.
也可以用 WALLET_CREDENTIAL 代替 PRIVATE_KEY。如果两个变量同时存在,值必须一致,否则会拒绝启动,避免误用账户。
Hardhat 配置需要在 ethers 和 OpenZeppelin 插件之后加载托管插件,并用 resolveHardhatAccounts 处理网络账户:
import "@nomicfoundation/hardhat-ethers";
import "@openzeppelin/hardhat-upgrades";
import "gate-evm-tools/hardhat";
import { resolveHardhatAccounts } from "gate-evm-tools/hardhat";
const walletCredential =
process.env.WALLET_CREDENTIAL ?? process.env.PRIVATE_KEY ?? "";
export default {
networks: {
sepolia: {
url: process.env.SEPOLIA_RPC_URL,
accounts: resolveHardhatAccounts(walletCredential),
},
},
};- 真实私钥返回给原生
networks.accounts,部署行为保持不变。 - 托管凭证让原生 accounts 保持为空,并自动替换
ethers.getSigners()、匹配地址的ethers.getSigner()和ethers.provider.getSigner(0)。 - 实际 ethers 主版本取自
hre.ethers.version;v5 使用运行时Signer,v6 使用运行时AbstractSigner,包内不会固定加载某个 ethers 版本。 - 业务部署脚本无需传入额外 signer;
ethers.getContractFactory()、deployContract()和upgrades.deployProxy()会取得托管 signer。 - 完整托管凭证通过 Bearer 发送,服务端拆解 Project Secret 与绑定钱包地址;凭证不会写入日志,每次签名请求都会生成独立的
Idempotency-Key。
托管服务只返回签名或 raw transaction,不负责广播。交易最终仍由当前 Hardhat ethers Provider 广播。现有 OpenZeppelin CREATE2/Multicall 补丁与 signer 注入是两套独立能力,升级项目应继续保留原补丁。
4. 编译合约
npx hardhat compile5. 使用工具
📋 查看帮助
npx gate-tool --help🔧 配置修复(推荐首次使用)
如果在使用过程中遇到 Hardhat 配置导入错误,可以使用 fix 命令自动修复:
# 自动检测并修复配置问题(交互式)
npx gate-tool fix
# 仅检查问题,不执行修复
npx gate-tool fix --check
# 跳过确认,直接修复
npx gate-tool fix --yes常见问题:
Cannot find module 'hardhat/config'- 导入语句需要使用type关键字Did you mean to import "hardhat/config.js"?- ESM 模块兼容性问题
fix 命令会自动将:
import { HardhatUserConfig } from "hardhat/config";修复为:
import type { HardhatUserConfig } from "hardhat/config";🔍 字节码检查
check、sync、validate 和 prepare 使用项目本地的 Hardhat,加载配置前自动注册 TypeScript;无需手动设置 NODE_OPTIONS=--require ts-node/register。项目仍需安装 Hardhat 所需的 ts-node / typescript。
# 检查 contractInfo.json 中全部网络的全部合约
npx gate-tool check
# 在配置中包含 Vault 的网络上检查该合约
npx gate-tool check --contract Vault
# 只检查指定网络;scheme 从 Hardhat 网络配置自动识别
npx gate-tool check --network eth
npx gate-tool check --network zkDev
# 也可以显式指定 scheme;不一致时报告错误
npx gate-tool check --network eth --scheme evm
# 自定义配置文件和输出路径
npx gate-tool check --config ./config/contracts.json --output ./reports/result.jsonnetwork.zksync === true 对应 zksync-eravm,其余 EVM 网络对应 evm;不会根据网络名称或 chainId 猜测。省略 --network 时,每个网络在独立子进程内初始化 Hardhat、编译并检查,再合并报告。这样混合 EVM/zkSync 项目不会共享同一个编译环境。显式 --scheme 对所有选中网络生效,不匹配会失败。
任一网络的配置、编译或字节码检查失败,整体退出码为 1;其余网络仍继续检查。编译失败不会消费旧 artifact,批量报告不会保留本次失败网络的旧成功结果。该自动识别规则适用于 check;sync 的 manifest/target 确认与显式 scheme 规则保持原有约束。
🔄 同步链上合约状态
当合约通过 calldata 方式由其他人(如多签钱包)执行升级后,本地的 .openzeppelin 文件不会自动更新。使用此命令可以从链上读取最新状态并更新本地文件。
sync 和 legacy validate 会在加载 OpenZeppelin upgrades 之前确定 manifest 目录。canonical workflow 的 sync --target 只接受所选 target 的 config.yaml.openzeppelin.manifestDir,不使用 Matter Labs 固定 .upgradable 目录。约定路由如下:
| 网络名 | Manifest 目录 | 含义 |
|------|------|------|
| bscDev 等以 Dev 结尾的网络 | .openzeppelin.dev | development 发布阶段 |
| bscProd 等以 Prod 结尾的网络 | .openzeppelin | production 发布阶段 |
| 其他远程网络 | 显式 MANIFEST_DEFAULT_DIR | 项目根目录下单层 .openzeppelin.<name> |
Dev/Prod 可以使用同一个 chainId 和 RPC,但代表两套独立合约状态。其他自定义网络必须显式设置安全的项目内目录,例如:
MANIFEST_DEFAULT_DIR=.openzeppelin.sepolia \
npx gate-tool sync --proxy 0x1234... --contract CounterUUPS --network sepolia--network 和 -n 都会在加载 command tree 前参与路由;自动化和迁移脚本建议始终使用完整的 --network。本地 hardhat、localhost、local、anvil 的 manifest 写入不支持:OpenZeppelin 会把 ephemeral development manifest 固定放到系统临时目录,所以 sync/validate 会明确拒绝,而不是声称写入某个项目内目录。
如果约定目录与 MANIFEST_DEFAULT_DIR 冲突、目录不明确、路径越界或经过符号链接,写 manifest 的命令会 fail closed,不会继续执行。
sync 和 validate 对同一 canonical manifest 使用同一把 gate-tool 锁。事务同时快照 canonical 文件与 OpenZeppelin fallback(如 unknown-{chainId}.json);若两者同时存在会在写入前拒绝,若 OpenZeppelin 把 fallback 移到 canonical 后流程失败,则按原始文件名和原始字节完整回滚。
sync 自己的补充写入使用原子替换。结果、精确 before/after 文件名和 hash 写入项目根目录的 per-manifest 报告,例如 development BSC 为 gate-tool-sync-report.openzeppelin.dev.bsc.json,production BSC 为 gate-tool-sync-report.openzeppelin.bsc.json。返回值中的 syncReport 是本次报告的权威路径;不要假设一个由 Dev/Prod 共享的固定报告名。
最新 full 模版项目优先使用 workflow:checkcode 做只读验收,由模版负责选择精确的 manifest 文件并调用 gate-tool。
# EVM:confirmed UUPS receipt 后同步合约状态
npx gate-tool sync \
--scheme evm \
--proxy 0x1234... \
--contract CounterUUPS \
--network sepolia \
--target sepolia
# zkSync:必须同时绑定 confirmed transaction hash
npx gate-tool sync \
--scheme zksync-eravm \
--proxy 0x1234... \
--contract CounterUUPS \
--network zkDev \
--target zkDev \
--transaction-hash 0x...sync 会验证 runtime code、ERC-1967 implementation slot、chain ID、UUPS kind 与当前 artifact/layout。只有 status=committed 的 manifest transaction 才能作为 finalized UUPS 证据;失败会恢复原文件名和原始字节。
✅ 验证升级安全性并生成 calldata
验证合约升级的安全性,并生成 upgradeToAndCall 的 calldata。
支持两种模式:
- 代理合约模式:验证升级安全性并生成 upgradeCalldata
- 实现合约模式:验证代码一致性并部署新合约
模式 1: 代理合约升级验证
# 不同合约升级(从 CounterUUPS 升级到 CounterUUPSV2)
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输出文件: upgradeCalldata.json
包含:
- 代理合约地址
- 旧实现合约地址
- 新实现合约地址
- upgradeToAndCall calldata
模式 2: 实现合约验证与部署
验证新合约与链上实现合约的存储布局兼容性,并部署新的实现合约。
# 验证存储布局兼容性并部署新合约
npx gate-tool validate \
--proxy 0xImplementationAddress \
--new LedgerImplA \
--network mainnet
# 注意:实现合约模式不需要 --old 参数工作流程:
- 🔍 自动检测地址类型(代理 or 实现)
- 📦 编译合约
- 🔐 验证存储布局兼容性(使用 Hardhat Upgrades 插件)
- ✅ 验证通过后部署新的实现合约
- 💾 保存部署信息到
implementationDeploy.json
输出文件: implementationDeploy.json
包含:
- 旧实现合约地址
- 新实现合约地址(新部署的)
- 存储布局兼容状态
- 时间戳和网络信息
使用场景:
- ✅ 验证新合约能否安全替换旧实现合约
- ✅ 确认存储槽位布局兼容
- ✅ 在验证通过后立即部署新的实现合约
- ✅ 获取新部署的实现合约地址用于后续升级
重要说明:
- 该模式不是比较代码完全一致
- 而是验证存储布局兼容性
- 即使代码有修改(如新增函数、修改逻辑),只要存储布局兼容就可以升级
- 这是可升级合约的核心安全机制
构造函数参数
# 如果新合约的构造函数需要参数
npx gate-tool validate \
--proxy 0x1234... \
--old CounterUUPS \
--new CounterUUPSV2 \
--network sepolia \
--constructor-args '["0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb", 100]'
# 构造函数参数示例
# 单个地址参数
--constructor-args '["0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb"]'
# 多个参数(地址 + 数值)
--constructor-args '["0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb", 1000000]'
# 复杂参数(地址 + 字符串 + 数值 + 布尔值)
--constructor-args '["0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb", "MyToken", 18, true]'工厂部署(可选)
如果需要通过工厂合约进行 Create2 部署,可以传入工厂地址(可选 salt)。
# 使用工厂合约部署新实现
npx gate-tool validate \
--proxy 0x1234... \
--old CounterUUPS \
--new CounterUUPSV2 \
--network sepolia \
--factory 0xFactoryAddress
# 指定 salt(bytes32)
npx gate-tool validate \
--proxy 0x1234... \
--old CounterUUPS \
--new CounterUUPSV2 \
--network sepolia \
--factory 0xFactoryAddress \
--factory-salt 0x0000000000000000000000000000000000000000000000000000000000001234说明:
- 不传
--factory时,默认走 EOA 部署逻辑 --factory-salt为可选,未传时默认使用全 0
注意:
- 代理模式:会部署新实现合约(仅用于验证),但不会升级代理合约。请使用生成的 calldata 通过多签钱包执行升级。
- 实现模式:会部署新实现合约并返回地址,可用于后续的手动升级操作。
构造函数参数格式说明:
--constructor-args 参数接受 JSON 数组格式的字符串。参数类型会自动根据合约定义进行匹配。
常见类型示例:
- 地址 (address):
"0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb" - 数值 (uint256/uint):
1000000或"1000000" - 字符串 (string):
"MyToken" - 布尔值 (bool):
true或false - 字节 (bytes):
"0x1234..."
示例:
// 合约构造函数
constructor(
address _token,
string memory _name,
uint256 _decimals,
bool _isPaused
) {
// ...
}对应的命令:
npx gate-tool validate \
--proxy 0x... \
--old OldContract \
--new NewContract \
--network mainnet \
--constructor-args '["0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb", "MyToken", 18, false]'📋 解析 Calldata
解析 EVM calldata,将其转换为人类可读的函数调用信息。
# 从 JSON 文件读取(推荐)
npx gate-tool parse --input parseCalldata.example.json
# 直接从命令行参数(使用合约名称从 artifacts 查找 ABI)
npx gate-tool parse \
--to 0x5FbDB2315678afecb367f032d93F642f64180aa3 \
--contract Counter \
--calldata 0x3fb5c1cb0000000000000000000000000000000000000000000000000000000000000064
# 使用自定义 ABI 文件
npx gate-tool parse \
--to 0x1234... \
--abi-path ./custom-abi/MyContract.json \
--calldata 0x...
# 批量解析并保存结果
npx gate-tool parse \
--input batch-calldata.json \
--output results.json输入文件格式示例:
{
"to": "0x5FbDB2315678afecb367f032d93F642f64180aa3",
"contractName": "Counter",
"calldata": "0x3fb5c1cb0000000000000000000000000000000000000000000000000000000000000064"
}批量解析格式(数组 包含三种形式):
[
{
"to": "0x...",
"contractName": "Counter",
"calldata": "0x..."
},
{
"to": "0x...",
"abiPath": "./abi.json",
"calldata": "0x..."
},
{
"": "0x...",
"abi": [
{
"inputs": [
{"name": "spender", "type": "address"},
{"name": "amount", "type": "uint256"}
],
"name": "approve",
"outputs": [{"name": "", "type": "bool"}],
"stateMutability": "nonpayable",
"type": "function"
}
],
"calldata": "0x..."
}
]支持三种 ABI 来源方式:
- contractName - 从 Hardhat artifacts 自动查找(需要先编译合约)
- abiPath - 指定 ABI 文件路径
- abi - 直接在 JSON 中提供 ABI 数组
6. 命令选项
check 命令
| 选项 | 简写 | 说明 | 默认值 |
|------|------|------|--------|
| --contract <name> | -c | 指定要检查的合约名称 | - |
| --network <name> | -n | 指定网络;省略时检查配置中的全部网络 | - |
| --scheme <scheme> | - | 可选;从 Hardhat 网络配置自动识别,显式值必须匹配 | - |
| --config <path> | - | 指定配置文件路径 | ./contractInfo.json |
| --output <path> | -o | 指定输出报告文件路径 | ./bytecode-check-report.json |
sync 命令
| 选项 | 简写 | 说明 | 必需 |
|------|------|------|------|
| --proxy <address> | - | 代理合约地址 | ✅ |
| --contract <name> | - | 合约名称 | ✅ |
| --network <name> | -n | 网络名称 | - |
| --scheme <scheme> | - | evm(默认)或 zksync-eravm | - |
| --target <name> | - | config.yaml 中的部署策略与 manifest target;zkSync 必需 | zkSync ✅ |
| --constructor-args <json> | - | 当前实现合约构造参数 JSON 数组 | - |
| --transaction-hash <hash> | - | 已确认的部署或升级交易哈希 | zkSync ✅ |
prepare 命令
| 选项 | 简写 | 说明 | 必需 |
|------|------|------|------|
| --network <name> | -n | Hardhat 网络;必须与 request.network 一致 | ✅ |
| --request <path> | - | 项目根目录内的严格 request JSON 文件 | ✅ |
| --output <path> | -o | 项目根目录内的 canonical plan JSON 文件 | ✅ |
validate 命令
| 选项 | 简写 | 说明 | 必需 |
|------|------|------|------|
| --proxy <address> | - | 代理合约地址 | ✅ |
| --old <name> | - | 旧合约名称(代理模式时使用) | - |
| --new <name> | - | 新合约名称 | ✅ |
| --network <name> | -n | 网络名称 | - |
| --output <path> | -o | 输出文件路径 | ./upgradeCalldata.json |
| --constructor-args <args> | - | 新合约构造函数参数(JSON数组格式) | - |
| --factory <address> | - | 工厂合约地址(可选,Create2 部署) | - |
| --factory-salt <salt> | - | 工厂部署 salt(bytes32,可选) | - |
parse 命令
| 选项 | 简写 | 说明 | 默认值 |
|------|------|------|--------|
| --input <path> | -i | 输入 JSON 文件路径 | - |
| --to <address> | - | 目标合约地址(命令行模式) | - |
| --calldata <data> | - | Calldata 十六进制数据(命令行模式) | - |
| --contract <name> | -c | 合约名称(从 artifacts 查找 ABI) | - |
| --abi-path <path> | - | 自定义 ABI 文件路径 | - |
| --output <path> | -o | 输出 JSON 文件路径 | - |
ABI 来源优先级:直接提供的 abi > abiPath > contractName
五、完整使用示例
场景 1: 验证实现合约存储布局并部署新版本
假设你有一个已部署的实现合约,需要验证新合约的存储布局兼容性并部署新版本:
# 1. 从 .openzeppelin 文件中找到实现合约地址
cat .openzeppelin/unknown-10088.json | grep "address"
# 2. 验证存储布局兼容性并部署新合约
npx gate-tool validate \
--proxy 0x40397e8F64561AabC793514F1b28B01A2ebE6875 \
--new LedgerImplA \
--network gateLayer
# 输出示例:
# ✅ 验证成功!
#
# 存储布局验证与部署结果:
# ────────────────────────────────────────────────────────────
# 旧实现合约: 0x40397e8F64561AabC793514F1b28B01A2ebE6875
# 新实现合约: 0x1234567890abcdef1234567890abcdef12345678
# 存储布局: ✅ 兼容
#
# 输出文件: /path/to/implementationDeploy.json
# ────────────────────────────────────────────────────────────
# 3. 查看部署信息
cat implementationDeploy.json输出文件内容:
{
"type": "implementation",
"oldImplementationAddress": "0x40397e8F64561AabC793514F1b28B01A2ebE6875",
"newImplementationAddress": "0x1234567890abcdef1234567890abcdef12345678",
"contractName": "LedgerImplA",
"storageLayoutCompatible": true,
"timestamp": "2024-01-01T00:00:00.000Z",
"network": "gateLayer"
}场景 2: 代理合约升级流程
# 1. 验证升级安全性并生成 calldata
npx gate-tool validate \
--proxy 0xProxyAddress \
--old CounterUUPS \
--new CounterUUPSV2 \
--network mainnet
# 输出示例:
# ✅ 验证成功!
#
# 升级信息摘要:
# ────────────────────────────────────────────────────────────
# 代理合约: 0xProxyAddress
# 旧实现: 0xOldImpl
# 新实现: 0xNewImpl
#
# Calldata: 0x4f1ef286000000000000000000000000...
#
# 输出文件: /path/to/upgradeCalldata.json
# ────────────────────────────────────────────────────────────
# 2. 使用生成的 calldata 在多签钱包中执行升级
# - 打开多签钱包(如 Gnosis Safe)
# - 使用 upgradeCalldata.json 中的 target 和 calldata
# - 提交交易并收集签名
# 3. 升级完成后,同步本地状态
npx gate-tool sync \
--proxy 0xProxyAddress \
--contract CounterUUPSV2 \
--network mainnet场景 3: 检查多个合约的字节码
# 1. 准备配置文件 contractInfo.json
cat > contractInfo.json << EOF
{
"contracts": {
"mainnet": {
"Vault": "0x1234...",
"Token": "0x5678..."
},
"sepolia": {
"Vault": "0xabcd..."
}
}
}
EOF
# 2. 执行检查
npx gate-tool check --network mainnet --scheme evm
# 3. 查看报告
cat bytecode-check-report.json场景 4: 解析升级交易的 calldata
# 1. 从多签钱包获取待执行的 calldata
# 2. 解析 calldata 查看具体操作
npx gate-tool parse \
--to 0xProxyAddress \
--contract CounterUUPS \
--calldata 0x4f1ef286000000000000000000000000...
# 输出示例:
# 📋 Calldata 解析结果
# ════════════════════════════════════════════════
# 目标合约: 0xProxyAddress
# 合约名称: CounterUUPS
#
# 函数名称: upgradeToAndCall
# 函数签名: upgradeToAndCall(address,bytes)
#
# 参数列表:
# ────────────────────────────────────────────────
# 1. newImplementation (address)
# 0x1234567890abcdef1234567890abcdef12345678
#
# 2. data (bytes)
# 0x
# ════════════════════════════════════════════════Historical EVM proxy checks first compare the current project artifact. If that
artifact is absent or differs, check can accept an exact full-runtime match
against the project's installed @openzeppelin/upgrades-core standard
ERC1967Proxy precompiled artifact (contracts-v5 or contracts). The report records
the package version, artifact path and SHA-256. This fallback does not strip
metadata, mask immutable values, accept arbitrary proxy code, or apply to EraVM
or implementation checks. It does not prove the proxy is unchanged since an
upgrade, or replace expected implementation-slot and storage-layout validation
in the deployment workflow. Unknown historical proxy builds still fail closed.
Full-template workflow runtime (local preview)
The full workflow is now packaged with GateTool. New templates call the package directly without project workflow/config forwarding directories; invocation uses npx --no-install gate-workflow. See runtime installation, migration and rollback. Version 1.0.27 is prepared for release; local tarball validation does not imply npm publication.
