gate-evm-tools 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +239 -0
  3. package/bin/cli.js +9 -0
  4. package/contractInfo.example.json +5 -0
  5. package/dist/commands/check.d.ts +6 -0
  6. package/dist/commands/check.d.ts.map +1 -0
  7. package/dist/commands/check.js +177 -0
  8. package/dist/commands/check.js.map +1 -0
  9. package/dist/commands/sync.d.ts +6 -0
  10. package/dist/commands/sync.d.ts.map +1 -0
  11. package/dist/commands/sync.js +97 -0
  12. package/dist/commands/sync.js.map +1 -0
  13. package/dist/commands/validate.d.ts +6 -0
  14. package/dist/commands/validate.d.ts.map +1 -0
  15. package/dist/commands/validate.js +108 -0
  16. package/dist/commands/validate.js.map +1 -0
  17. package/dist/core/bytecodeChecker.d.ts +105 -0
  18. package/dist/core/bytecodeChecker.d.ts.map +1 -0
  19. package/dist/core/bytecodeChecker.js +413 -0
  20. package/dist/core/bytecodeChecker.js.map +1 -0
  21. package/dist/core/syncUpgradeJson.d.ts +23 -0
  22. package/dist/core/syncUpgradeJson.d.ts.map +1 -0
  23. package/dist/core/syncUpgradeJson.js +260 -0
  24. package/dist/core/syncUpgradeJson.js.map +1 -0
  25. package/dist/core/validateAndGenerateCalldata.d.ts +26 -0
  26. package/dist/core/validateAndGenerateCalldata.d.ts.map +1 -0
  27. package/dist/core/validateAndGenerateCalldata.js +235 -0
  28. package/dist/core/validateAndGenerateCalldata.js.map +1 -0
  29. package/dist/index.d.ts +2 -0
  30. package/dist/index.d.ts.map +1 -0
  31. package/dist/index.js +80 -0
  32. package/dist/index.js.map +1 -0
  33. package/dist/types.d.ts +41 -0
  34. package/dist/types.d.ts.map +1 -0
  35. package/dist/types.js +2 -0
  36. package/dist/types.js.map +1 -0
  37. package/dist/utils/files.d.ts +18 -0
  38. package/dist/utils/files.d.ts.map +1 -0
  39. package/dist/utils/files.js +75 -0
  40. package/dist/utils/files.js.map +1 -0
  41. package/dist/utils/output.d.ts +14 -0
  42. package/dist/utils/output.d.ts.map +1 -0
  43. package/dist/utils/output.js +67 -0
  44. package/dist/utils/output.js.map +1 -0
  45. package/package.json +60 -0
package/dist/index.js ADDED
@@ -0,0 +1,80 @@
1
+ import { Command } from 'commander';
2
+ import chalk from 'chalk';
3
+ import { checkBytecode } from './commands/check.js';
4
+ import { syncUpgrade } from './commands/sync.js';
5
+ import { validateUpgrade } from './commands/validate.js';
6
+ import { readFileSync } from 'fs';
7
+ import { fileURLToPath } from 'url';
8
+ import { dirname, join } from 'path';
9
+ const __filename = fileURLToPath(import.meta.url);
10
+ const __dirname = dirname(__filename);
11
+ // 读取 package.json 获取版本号
12
+ const packageJson = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf-8'));
13
+ const program = new Command();
14
+ program
15
+ .name('gate-tool')
16
+ .description('🛠️ Gate 智能合约工具集 - 字节码检查、合约升级验证')
17
+ .version(packageJson.version, '-v, --version', '显示版本号');
18
+ // check 命令
19
+ program
20
+ .command('check')
21
+ .description('执行字节码检查')
22
+ .option('-c, --contract <name>', '指定要检查的合约名称')
23
+ .option('-n, --network <name>', '指定要检查的网络名称')
24
+ .option('--config <path>', '指定配置文件路径 (默认: ./contractInfo.json)')
25
+ .option('-o, --output <path>', '指定输出报告文件路径 (默认: ./bytecode-check-report.json)')
26
+ .action(async (options) => {
27
+ try {
28
+ await checkBytecode(options);
29
+ }
30
+ catch (error) {
31
+ console.error(chalk.red('\n❌ 执行失败:'), error.message);
32
+ process.exit(1);
33
+ }
34
+ });
35
+ // sync 命令
36
+ program
37
+ .command('sync')
38
+ .description('同步链上合约状态到本地 .openzeppelin 文件')
39
+ .requiredOption('--proxy <address>', '代理合约地址')
40
+ .requiredOption('--contract <name>', '合约名称')
41
+ .option('-n, --network <name>', '网络名称')
42
+ .action(async (options) => {
43
+ try {
44
+ await syncUpgrade(options);
45
+ }
46
+ catch (error) {
47
+ console.error(chalk.red('\n❌ 执行失败:'), error.message);
48
+ process.exit(1);
49
+ }
50
+ });
51
+ // validate 命令
52
+ program
53
+ .command('validate')
54
+ .description('验证合约升级安全性并生成 calldata')
55
+ .requiredOption('--proxy <address>', '代理合约地址')
56
+ .requiredOption('--old <name>', '旧合约名称')
57
+ .requiredOption('--new <name>', '新合约名称')
58
+ .option('-n, --network <name>', '网络名称')
59
+ .option('-o, --output <path>', '输出文件路径 (默认: ./upgradeCalldata.json)')
60
+ .action(async (options) => {
61
+ try {
62
+ await validateUpgrade(options);
63
+ }
64
+ catch (error) {
65
+ console.error(chalk.red('\n❌ 执行失败:'), error.message);
66
+ process.exit(1);
67
+ }
68
+ });
69
+ // 显示帮助信息(无命令时)
70
+ program.action(() => {
71
+ program.outputHelp();
72
+ });
73
+ export async function run() {
74
+ program.parse(process.argv);
75
+ // 如果没有提供命令,显示帮助
76
+ if (!process.argv.slice(2).length) {
77
+ program.outputHelp();
78
+ }
79
+ }
80
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ export interface ContractInfo {
2
+ name: string;
3
+ address: string;
4
+ network: string;
5
+ }
6
+ export interface CheckResult {
7
+ contract: string;
8
+ contractName: string;
9
+ network: string;
10
+ address: string;
11
+ matches: boolean;
12
+ error: string | null;
13
+ reason: string;
14
+ onChainBytecodeLength: number;
15
+ localBytecodeLength: number;
16
+ }
17
+ export interface NetworkConfig {
18
+ [contractName: string]: string;
19
+ }
20
+ export interface ContractConfig {
21
+ [network: string]: NetworkConfig;
22
+ }
23
+ export interface CheckOptions {
24
+ contract?: string;
25
+ network?: string;
26
+ config?: string;
27
+ output?: string;
28
+ }
29
+ export interface SyncOptions {
30
+ proxy: string;
31
+ contract: string;
32
+ network?: string;
33
+ }
34
+ export interface ValidateOptions {
35
+ proxy: string;
36
+ old: string;
37
+ new: string;
38
+ network?: string;
39
+ output?: string;
40
+ }
41
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,qBAAqB,EAAE,MAAM,CAAC;IAC9B,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,aAAa;IAC5B,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,cAAc;IAC7B,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,CAAC;CAClC;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,18 @@
1
+ import { ContractConfig } from '../types.js';
2
+ /**
3
+ * 查找配置文件
4
+ */
5
+ export declare function findConfigFile(configPath?: string): string;
6
+ /**
7
+ * 读取配置文件
8
+ */
9
+ export declare function readConfigFile(configPath: string): ContractConfig;
10
+ /**
11
+ * 保存报告文件
12
+ */
13
+ export declare function saveReport(data: any, outputPath?: string): string;
14
+ /**
15
+ * 合并报告(增量更新)
16
+ */
17
+ export declare function mergeReports(existingReport: any, newResults: any): any;
18
+ //# sourceMappingURL=files.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../../src/utils/files.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C;;GAEG;AACH,wBAAgB,cAAc,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CA6B1D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,CAOjE;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,GAAG,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAYjE;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,cAAc,EAAE,GAAG,EAAE,UAAU,EAAE,GAAG,GAAG,GAAG,CActE"}
@@ -0,0 +1,75 @@
1
+ import fs from 'fs-extra';
2
+ import path from 'path';
3
+ /**
4
+ * 查找配置文件
5
+ */
6
+ export function findConfigFile(configPath) {
7
+ const cwd = process.cwd();
8
+ // 如果用户指定了配置文件路径
9
+ if (configPath) {
10
+ const absolutePath = path.isAbsolute(configPath) ? configPath : path.join(cwd, configPath);
11
+ if (fs.existsSync(absolutePath)) {
12
+ return absolutePath;
13
+ }
14
+ throw new Error(`配置文件不存在: ${configPath}`);
15
+ }
16
+ // 默认查找位置
17
+ const defaultPaths = [
18
+ path.join(cwd, 'contractInfo.json'),
19
+ path.join(cwd, 'config', 'contractInfo.json'),
20
+ path.join(cwd, 'contracts', 'contractInfo.json'),
21
+ ];
22
+ for (const filePath of defaultPaths) {
23
+ if (fs.existsSync(filePath)) {
24
+ return filePath;
25
+ }
26
+ }
27
+ throw new Error('未找到配置文件 contractInfo.json,请在项目根目录或 config/ 或 contracts/ 目录下创建配置文件,' +
28
+ '或使用 --config 参数指定配置文件路径');
29
+ }
30
+ /**
31
+ * 读取配置文件
32
+ */
33
+ export function readConfigFile(configPath) {
34
+ try {
35
+ const content = fs.readFileSync(configPath, 'utf-8');
36
+ return JSON.parse(content);
37
+ }
38
+ catch (error) {
39
+ throw new Error(`读取配置文件失败: ${error.message}`);
40
+ }
41
+ }
42
+ /**
43
+ * 保存报告文件
44
+ */
45
+ export function saveReport(data, outputPath) {
46
+ const cwd = process.cwd();
47
+ const reportPath = outputPath
48
+ ? (path.isAbsolute(outputPath) ? outputPath : path.join(cwd, outputPath))
49
+ : path.join(cwd, 'bytecode-check-report.json');
50
+ try {
51
+ fs.writeFileSync(reportPath, JSON.stringify(data, null, 2), 'utf-8');
52
+ return reportPath;
53
+ }
54
+ catch (error) {
55
+ throw new Error(`保存报告失败: ${error.message}`);
56
+ }
57
+ }
58
+ /**
59
+ * 合并报告(增量更新)
60
+ */
61
+ export function mergeReports(existingReport, newResults) {
62
+ const merged = { ...existingReport };
63
+ for (const [networkName, networkData] of Object.entries(newResults)) {
64
+ if (!merged[networkName]) {
65
+ merged[networkName] = networkData;
66
+ }
67
+ else {
68
+ const existingNetwork = merged[networkName];
69
+ const newNetwork = networkData;
70
+ merged[networkName] = { ...existingNetwork, ...newNetwork };
71
+ }
72
+ }
73
+ return merged;
74
+ }
75
+ //# sourceMappingURL=files.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"files.js","sourceRoot":"","sources":["../../src/utils/files.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { CheckResult } from '../types.js';
2
+ /**
3
+ * 打印检查结果摘要
4
+ */
5
+ export declare function printSummary(results: CheckResult[]): void;
6
+ /**
7
+ * 打印进度信息
8
+ */
9
+ export declare function printProgress(message: string, type?: 'info' | 'success' | 'error' | 'warning'): void;
10
+ /**
11
+ * 打印配置信息
12
+ */
13
+ export declare function printConfig(config: any, configPath: string): void;
14
+ //# sourceMappingURL=output.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../src/utils/output.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,WAAW,EAAE,QA2ClD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,SAAkB,QASrG;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,QAS1D"}
@@ -0,0 +1,67 @@
1
+ import chalk from 'chalk';
2
+ /**
3
+ * 打印检查结果摘要
4
+ */
5
+ export function printSummary(results) {
6
+ console.log('\n' + '='.repeat(80));
7
+ console.log(chalk.bold.cyan('字节码检查报告'));
8
+ console.log('='.repeat(80));
9
+ const matches = results.filter(r => r.matches && !r.error);
10
+ const mismatches = results.filter(r => !r.matches && !r.error);
11
+ const errors = results.filter(r => r.error);
12
+ console.log(`\n${chalk.bold('总计检查:')} ${results.length}`);
13
+ console.log(`${chalk.green('✓ 匹配:')} ${matches.length}`);
14
+ console.log(`${chalk.red('✗ 不匹配:')} ${mismatches.length}`);
15
+ console.log(`${chalk.yellow('⚠ 错误:')} ${errors.length}`);
16
+ if (mismatches.length > 0) {
17
+ console.log('\n' + chalk.red.bold('❌ 不匹配的合约:'));
18
+ console.log('-'.repeat(80));
19
+ mismatches.forEach(result => {
20
+ console.log(chalk.red(`\n${result.contract} (${result.network})`));
21
+ console.log(` 地址: ${chalk.gray(result.address)}`);
22
+ console.log(` 原因: ${result.reason}`);
23
+ console.log(` 链上字节码长度: ${result.onChainBytecodeLength}`);
24
+ console.log(` 本地字节码长度: ${result.localBytecodeLength}`);
25
+ });
26
+ }
27
+ if (matches.length > 0) {
28
+ console.log('\n' + chalk.green.bold('✅ 匹配的合约:'));
29
+ console.log('-'.repeat(80));
30
+ matches.forEach(result => {
31
+ console.log(chalk.green(`${result.contract} (${result.network}): ${result.reason}`));
32
+ });
33
+ }
34
+ if (errors.length > 0) {
35
+ console.log('\n' + chalk.yellow.bold('⚠ 错误:'));
36
+ console.log('-'.repeat(80));
37
+ errors.forEach(result => {
38
+ console.log(chalk.yellow(`${result.contract} (${result.network}): ${result.error}`));
39
+ });
40
+ }
41
+ console.log('\n' + '='.repeat(80) + '\n');
42
+ }
43
+ /**
44
+ * 打印进度信息
45
+ */
46
+ export function printProgress(message, type = 'info') {
47
+ const icons = {
48
+ info: chalk.cyan('ℹ'),
49
+ success: chalk.green('✓'),
50
+ error: chalk.red('✗'),
51
+ warning: chalk.yellow('⚠')
52
+ };
53
+ console.log(`${icons[type]} ${message}`);
54
+ }
55
+ /**
56
+ * 打印配置信息
57
+ */
58
+ export function printConfig(config, configPath) {
59
+ console.log(chalk.cyan('\n配置文件:'), chalk.gray(configPath));
60
+ console.log(chalk.cyan('网络数量:'), Object.keys(config).length);
61
+ for (const [network, contracts] of Object.entries(config)) {
62
+ const contractCount = Object.keys(contracts).length;
63
+ console.log(chalk.cyan(` - ${network}:`), `${contractCount} 个合约`);
64
+ }
65
+ console.log();
66
+ }
67
+ //# sourceMappingURL=output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/utils/output.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "gate-evm-tools",
3
+ "version": "1.0.0",
4
+ "description": "Gate 智能合约工具集 - 字节码检查、合约升级验证、合约状态同步",
5
+ "type": "module",
6
+ "bin": {
7
+ "gate-tool": "./bin/cli.js"
8
+ },
9
+ "files": [
10
+ "bin/",
11
+ "dist/",
12
+ "README.md",
13
+ "contractInfo.example.json"
14
+ ],
15
+ "scripts": {
16
+ "build": "tsc",
17
+ "dev": "tsc --watch",
18
+ "start": "node bin/cli.js",
19
+ "test": "node bin/cli.js check"
20
+ },
21
+ "keywords": [
22
+ "bytecode",
23
+ "hardhat",
24
+ "ethereum",
25
+ "solidity",
26
+ "verification",
27
+ "cli",
28
+ "upgrade",
29
+ "uups",
30
+ "proxy",
31
+ "openzeppelin"
32
+ ],
33
+ "author": "",
34
+ "license": "MIT",
35
+ "dependencies": {
36
+ "chalk": "^5.3.0",
37
+ "commander": "^11.1.0",
38
+ "fs-extra": "^11.2.0",
39
+ "ora": "^7.0.1",
40
+ "prompts": "^2.4.2"
41
+ },
42
+ "devDependencies": {
43
+ "@openzeppelin/hardhat-upgrades": "^3.9.1",
44
+ "@openzeppelin/upgrades-core": "^1.44.2",
45
+ "@types/fs-extra": "^11.0.4",
46
+ "@types/node": "^24.7.2",
47
+ "@types/prompts": "^2.4.9",
48
+ "ethers": "^6.15.0",
49
+ "typescript": "^5.9.3"
50
+ },
51
+ "peerDependencies": {
52
+ "@openzeppelin/hardhat-upgrades": "^2.5.0",
53
+ "@openzeppelin/upgrades-core": "^1.0.0",
54
+ "ethers": "^6.0.0",
55
+ "hardhat": "^2.26.3"
56
+ },
57
+ "engines": {
58
+ "node": ">=18.0.0"
59
+ }
60
+ }