Files
assetxContracts/README.md
2025-12-18 13:07:35 +08:00

346 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Hardhat2 + Foundry EVM 开发框架
这是一个将 Hardhat 与 Foundry 无缝整合的 Solidity 开发框架,既保留了 Hardhat 的插件生态部署、验证、脚本执行、TypeScript 开发体验),也利用 Foundry 的高速 EVM、测试与脚本执行能力。适用于复杂合约开发、测试驱动开发 (TDD)、多环境部署与高级调试需求。
## create2 factory
框架通过魔改 hardhdat-upgrade 包实现可以指定各条链的factory合约地址使用create2部署地址一样的合约。
注意调用factory部署合约时需要确定你的地址拥有factory合约的admin权限否则会失败。
可升级合约使用方式想要使用factory部署在调用upgrades.deployProxy时指定create2Factory配置即可。否则不指定create2Factory配置就是非create2 factory模式进行部署
```bash
const ContractFactory = await ethers.getContractFactory(CONTRACT_NAME);
const INIT_ARGS: any[] = [];
const create2Config = {
address: FACTORY_ADDRESS,
salt: proxySalt, // 代理合约的 salt
implSalt: implSalt, // 实现合约的 salt
deployImpl: true, // 实现合约也用 CREATE2 部署
};
const contract = await upgrades.deployProxy(
ContractFactory,
INIT_ARGS,
{
initializer: 'initialize',
kind: 'uups',
...( { create2Factory: create2Config } as any ),
}
);
```
不可升级合约使用方式不想使用factory部署直接调用Yourcontract.deploy即可
```bash
const ContractFactory = await ethers.getContractFactory('YourContract');
const bytecode = ContractFactory.bytecode;
const constructorArgs = ethers.AbiCoder.defaultAbiCoder().encode(
['uint256'], // 构造函数参数类型
[123] // 构造函数参数值
);
const initCode = ethers.concat([bytecode, constructorArgs]);
const factoryContract = await ethers.getContractAt(
['function deploy(bytes32 salt, bytes memory initCode, bytes memory data, uint256 create2ForwardValue, uint256 callForwardValue) external payable returns (address)'],
FACTORY_ADDRESS
);
const tx = await factoryContract.deploy(
salt,
initCode,
'0x', // 部署后不需要额外调用
0, // create2ForwardValue
0 // callForwardValue
);
```
同时本项目集成了 check / sync / validate / parse 四个核心命令,构建出一套完整的智能合约升级与安全验证流程。
额外带有修复hardhat-config.ts文件引用错误的功能 fix使用evm-hardhat-foundry包部署的框架则不会用到此功能,以往项目可能会用到,例如错误引用import { HardhatUserConfig } from "hardhat/config";
## 功能特性
功能一: 字节码检查check
功能二: 合约状态同步sync
功能三: 升级验证validate
功能四: Calldata解析parse
功能五: hardhat-config.ts文件修复fix
### 功能一: 字节码检查check
- ✅ 检查链下合约代码和链上合约代码是否一致
- ✅ 支持检查单个合约、指定网络或所有合约
- ✅ 智能识别 Constructor 参数差异和 Immutable 变量差异
- ✅ 自动移除元数据进行比较
- ✅ 生成详细的 JSON 报告
- ✅ 支持增量更新报告
#### 1. 修改配置文件
在项目根目录创建 `contractInfo.json` 文件:
```json
{
"eth": {
"Vault": "0x80aaf2e4636c510e067a5d300d8bafd48027addf",
"VaultCrossChainRelay": "0x060194eec4556096baaabd6bf553d2658d6a66ab"
},
"bsc": {
"Vault": "0x2cb7d2603a5f43b9fe79e98f09fe3eec40b6765d",
"VaultCrossChainRelay": "0x23ae3a565e0896866e7725fe6d49fd777359c162"
}
}
```
格式说明:
- 第一层 key 是网络名称(必须与 `hardhat.config.js` 中的网络名称一致)
- 第二层 key 是合约名称(必须与编译的合约名称一致)
- value 是合约地址
#### 2. 配置 Hardhat
确保 `hardhat.config.js` 中配置了相应的网络:
```javascript
module.exports = {
networks: {
eth: {
url: "https://eth-mainnet.g.alchemy.com/v2/YOUR-API-KEY",
},
bsc: {
url: "https://bsc-dataseed.binance.org/",
}
}
};
```
#### 3. 使用工具
##### 📋 查看帮助
```bash
npx gate-tool --help
```
##### 🔍 字节码检查
```bash
# 检查所有合约(推荐)
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
```
### 功能二: 合约状态同步sync
- ✅ 同步链上合约状态到本地 .openzeppelin 文件
- ✅ 自动读取链上实现合约地址
- ✅ 获取并更新存储布局信息
#### 1. 同步链上合约状态
当合约通过 calldata 方式由其他人(如多签钱包)执行升级后,本地的 `.openzeppelin` 文件不会自动更新。使用此命令可以从链上读取最新状态并更新本地文件。
```bash
# 同步合约状态(推荐)
npx gate-tool sync \
--proxy 0x1234... \
--contract CounterUUPS \
--network sepolia
```
### 功能三: 升级验证validate
- ✅ 验证合约升级的安全性
- ✅ 检查存储布局兼容性
- ✅ 自动部署新实现合约
- ✅ 生成 upgradeToAndCall 的 calldata
- ✅ 支持同一合约和不同合约的升级模式
#### 1. 验证升级安全性并生成 calldata
验证合约升级的安全性,并生成 `upgradeToAndCall` 的 calldata。
```bash
# 不同合约升级(从 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
```
**注意:** `validate` 命令会在链上部署新的实现合约(仅用于验证),但不会升级代理合约。请使用生成的 calldata 通过多签钱包执行升级。
### 功能四: Calldata 解析parse
- ✅ 解析 EVM calldata显示函数名称和参数
- ✅ 支持从 Hardhat artifacts 自动查找 ABI
- ✅ 支持指定自定义 ABI 文件路径
- ✅ 支持直接提供 ABI 数组
- ✅ 支持批量解析多个 calldata
- ✅ 友好的彩色输出和 JSON 导出
#### 1. 解析 Calldata
解析 EVM calldata将其转换为人类可读的函数调用信息。
```bash
# 从 JSON 文件单个或批量读取(推荐)
npx gate-tool parse --input parseCalldata.example.json --output results.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...
**输入文件格式示例:**
```json
{
"to": "0x5FbDB2315678afecb367f032d93F642f64180aa3",
"contractName": "Counter",
"calldata": "0x3fb5c1cb0000000000000000000000000000000000000000000000000000000000000064"
}
```
**批量解析格式(数组 包含三种形式):**
```json
[
{
"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 来源方式:
1. **contractName** - 从 Hardhat artifacts 自动查找(需要先编译合约)
2. **abiPath** - 指定 ABI 文件路径
3. **abi** - 直接在 JSON 中提供 ABI 数组
### 功能五: 配置修复fix
- ✅ 自动检测 Hardhat 配置文件的兼容性问题
- ✅ 智能修复 ESM 模块导入错误
- ✅ 交互式确认修复操作
- ✅ 自动备份原配置文件
- ✅ 支持仅检查模式
#### 1. 配置修复(推荐首次使用)
如果在使用过程中遇到 Hardhat 配置导入错误,可以使用 `fix` 命令自动修复:
```bash
# 自动检测并修复配置问题(推荐 交互式)
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` 命令会自动将:
```typescript
import { HardhatUserConfig } from "hardhat/config";
```
修复为:
```typescript
import type { HardhatUserConfig } from "hardhat/config";
```
## 命令选项
### 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` |
#### 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