init: 初始化 AssetX 项目仓库
包含 webapp(Next.js 用户端)、webapp-back(Go 后端)、 antdesign(管理后台)、landingpage(营销落地页)、 数据库 SQL 和配置文件。
This commit is contained in:
141
webapp-back/tools/verify_contracts.js
Normal file
141
webapp-back/tools/verify_contracts.js
Normal file
@@ -0,0 +1,141 @@
|
||||
// 合约验证和部署区块查询工具
|
||||
// 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);
|
||||
Reference in New Issue
Block a user