Files
assetx/webapp-back/tools/verify_contracts.js
default 2ee4553b71 init: 初始化 AssetX 项目仓库
包含 webapp(Next.js 用户端)、webapp-back(Go 后端)、
antdesign(管理后台)、landingpage(营销落地页)、
数据库 SQL 和配置文件。
2026-03-27 11:26:43 +00:00

142 lines
5.7 KiB
JavaScript
Raw Permalink 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.

// 合约验证和部署区块查询工具
// Contract verification and deployment block query tool
const { ethers } = require("ethers");
// 配置
const RPC_URL = "https://sepolia-rollup.arbitrum.io/rpc";
// 你数据库中的合约地址
const CONTRACTS = {
"YT-A": "0x7f9eEA491eE53045594ee4669327f0355aCd0e58",
"YT-B": "0x20B94C5E5b7361552E0548161a58696aA6FeDBd4",
"YT-C": "0x0EF308D70cf35460E26a3Eb42F3442Ff28cbE07C",
"ytLP": "0x102e3F25Ef0ad9b0695C8F2daF8A1262437eEfc3",
"Lending": "0xCb4E7B1069F6C26A1c27523ce4c8dfD884552d1D"
};
// ERC20 ABI (只包含必要的函数)
const ERC20_ABI = [
"function name() view returns (string)",
"function symbol() view returns (string)",
"function totalSupply() view returns (uint256)",
"function balanceOf(address) view returns (uint256)"
];
async function verifyContract(provider, name, address) {
console.log(`\n━━━ ${name} ━━━`);
console.log(`地址: ${address}`);
try {
// 检查合约代码
const code = await provider.getCode(address);
if (code === "0x") {
console.log("❌ 错误: 该地址没有合约代码(可能是错误的地址)");
return null;
}
console.log("✅ 合约代码存在");
// 尝试读取 ERC20 信息(仅适用于 YT 和 ytLP
if (name.startsWith("YT-") || name === "ytLP") {
try {
const contract = new ethers.Contract(address, ERC20_ABI, provider);
const [tokenName, symbol, totalSupply] = await Promise.all([
contract.name(),
contract.symbol(),
contract.totalSupply()
]);
console.log(` 名称: ${tokenName}`);
console.log(` 符号: ${symbol}`);
console.log(` 总供应量: ${ethers.formatEther(totalSupply)} (${totalSupply.toString()})`);
} catch (error) {
console.log("⚠️ 无法读取 ERC20 信息(可能不是标准 ERC20");
}
}
// 尝试获取创建交易(需要手动在 Arbiscan 查询)
console.log(`\n🔍 在 Arbiscan 上查询部署信息:`);
console.log(` https://sepolia.arbiscan.io/address/${address}`);
return { address, hasCode: true };
} catch (error) {
console.log(`❌ 错误: ${error.message}`);
return null;
}
}
async function suggestDeploymentBlock(provider) {
console.log("\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
console.log("📍 部署区块建议");
console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n");
const currentBlock = await provider.getBlockNumber();
console.log(`当前最新区块: ${currentBlock}`);
console.log(`\n如果你不知道确切的部署区块号,可以使用以下策略:\n`);
console.log(`方案 1 (推荐): 在 Arbiscan 上查询准确的部署区块`);
console.log(` - 访问上面的链接,查看 "Contract Creation" 交易`);
console.log(` - 使用准确的部署区块可以确保不遗漏任何数据\n`);
console.log(`方案 2 (临时): 使用较近的区块号进行测试`);
console.log(` - 从较新的区块开始扫描(例如: ${currentBlock - 100000}`);
console.log(` - 可以快速测试功能,但可能遗漏早期持有者数据\n`);
console.log(`方案 3 (保守): 使用较早的区块号`);
console.log(` - 从一个足够早的区块开始(例如: 227000000`);
console.log(` - 可能扫描大量无关区块,但能确保完整性`);
}
async function main() {
console.log("=== 合约验证工具 ===\n");
console.log(`RPC: ${RPC_URL}\n`);
const provider = new ethers.JsonRpcProvider(RPC_URL);
// 验证连接
try {
const network = await provider.getNetwork();
console.log(`✅ 已连接到网络: ${network.name} (Chain ID: ${network.chainId})\n`);
} catch (error) {
console.log(`❌ 无法连接到 RPC: ${error.message}`);
process.exit(1);
}
// 验证每个合约
const results = {};
for (const [name, address] of Object.entries(CONTRACTS)) {
const result = await verifyContract(provider, name, address);
results[name] = result;
}
// 显示摘要
console.log("\n\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
console.log("📊 验证摘要");
console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n");
const validContracts = Object.entries(results).filter(([_, r]) => r?.hasCode);
const invalidContracts = Object.entries(results).filter(([_, r]) => !r?.hasCode);
console.log(`✅ 有效合约: ${validContracts.length}/${Object.keys(CONTRACTS).length}`);
validContracts.forEach(([name]) => console.log(`${name}`));
if (invalidContracts.length > 0) {
console.log(`\n❌ 无效合约: ${invalidContracts.length}`);
invalidContracts.forEach(([name]) => console.log(`${name}`));
}
// 部署区块建议
await suggestDeploymentBlock(provider);
console.log("\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
console.log("📝 下一步");
console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n");
console.log("1. 在 Arbiscan 上查询每个合约的部署区块号");
console.log("2. 更新 .env 文件中的部署区块号:");
console.log(" YT_VAULTS_DEPLOY_BLOCK=<实际区块号>");
console.log(" YTLP_DEPLOY_BLOCK=<实际区块号>");
console.log(" LENDING_DEPLOY_BLOCK=<实际区块号>");
console.log("3. 运行 Scanner:");
console.log(" ./run-scanner.sh");
console.log("");
}
main().catch(console.error);