import "dotenv/config" import { ethers } from "ethers" import * as fs from "fs" import * as path from "path" import { MockUSD1__factory, BasicERC20__factory } from "../typechain-types/factories/contracts" import type { MockUSD1, BasicERC20 } from "../typechain-types/contracts" // NonceManager类用于管理nonce class NonceManager { private nonce: number private provider: ethers.Provider private address: string constructor(provider: ethers.Provider, address: string, initialNonce?: number) { this.provider = provider this.address = address this.nonce = initialNonce || 0 } async getNextNonce(): Promise { if (this.nonce === 0) { // 从网络获取当前nonce const currentNonce = await this.provider.getTransactionCount(this.address) this.nonce = currentNonce } return this.nonce++ } async resetNonce(): Promise { const currentNonce = await this.provider.getTransactionCount(this.address) this.nonce = currentNonce } } async function main() { // 获取环境配置 const environment = process.env.ENVIRONMENT || "bsctest" const rpcUrl = process.env.RPC_URL || "https://data-seed-prebsc-1-s1.binance.org:8545/" const outputDir = process.env.OUTPUT_DIR || "./output/bsctest" console.log(`🚀 第2步:向所有账户分发测试代币...`) console.log(`🌍 环境: ${environment}`) console.log(`🔗 RPC: ${rpcUrl}`) console.log(`📁 输出目录: ${outputDir}`) // 检查环境变量 if (!process.env.PRIVATE_KEY) { console.error("❌ 需要设置 PRIVATE_KEY 环境变量") process.exit(1) } // 从之前的步骤加载合约地址 const contractAddressesPath = path.join(outputDir, "contract-addresses.json") if (!fs.existsSync(contractAddressesPath)) { console.error(`❌ 未找到 ${contractAddressesPath} 文件。请先运行第1步。`) process.exit(1) } const contractAddresses = JSON.parse(fs.readFileSync(contractAddressesPath, "utf8")) console.log("📋 已从之前的步骤加载合约地址") // 设置提供者和部署者 const provider = new ethers.JsonRpcProvider(rpcUrl) const deployer = new ethers.Wallet(process.env.PRIVATE_KEY, provider) // 为部署者初始化NonceManager const nonceManager = new NonceManager(provider, deployer.address) // 连接到已部署的合约 const mockUSD1 = MockUSD1__factory.connect(contractAddresses.mockUSD1, deployer) // 从JSON文件加载测试账户 const testAccountsPath = "./scripts/testAccount/BLaunchpadTest.json" if (!fs.existsSync(testAccountsPath)) { console.error("❌ 未找到测试账户文件:", testAccountsPath) process.exit(1) } const testAccounts = JSON.parse(fs.readFileSync(testAccountsPath, "utf8")) console.log("📋 已从", testAccountsPath, "加载", testAccounts.length, "个测试账户") // 向所有测试账户分发MockUSD1 console.log("\n💰 向所有测试账户分发MockUSD1...") const usd1Amount = ethers.parseEther("20000") // 每个账户20K USD1 for (let i = 0; i < testAccounts.length; i++) { const account = testAccounts[i] const userWallet = new ethers.Wallet(account.privateKey, provider) const tokenBalance = await mockUSD1.balanceOf(userWallet.address) // 如果余额不足20K,需要补充 if (tokenBalance < ethers.parseEther("20000")) { const needToMint = ethers.parseEther("20000") - tokenBalance try { const nonce = await nonceManager.getNextNonce() const tx = await mockUSD1.connect(deployer).mint(userWallet.address, needToMint, { nonce }) console.log(`✅ 账户 ${i + 1}: ${userWallet.address} - 补充 ${ethers.formatEther(needToMint)} USD1 (总计: ${ethers.formatEther(usd1Amount)})`) } catch (error) { console.error(`❌ 为账户 ${i + 1} 铸造USD1失败:`, error) // 出错时重置nonce await nonceManager.resetNonce() } } else { console.log(`✅ 账户 ${i + 1}: ${userWallet.address} - 已有足够余额 ${ethers.formatEther(tokenBalance)} USD1`) } } // 向所有测试账户分发真实BNB作为gas费用 console.log("\n💰 向所有测试账户分发BNB作为gas费用...") const bnbGasAmount = ethers.parseEther("0.01") // 每个账户0.01 BNB用于gas for (let i = 0; i < testAccounts.length; i++) { const account = testAccounts[i] const userWallet = new ethers.Wallet(account.privateKey, provider) const balance = await provider.getBalance(userWallet.address) if (balance < bnbGasAmount) { try { const nonce = await nonceManager.getNextNonce() const tx = await deployer.sendTransaction({ to: userWallet.address, value: bnbGasAmount, nonce: nonce, }) await tx.wait() console.log(`✅ 账户 ${i + 1}: ${userWallet.address} - ${ethers.formatEther(bnbGasAmount)} BNB用于gas`) } catch (error) { console.error(`❌ 向账户 ${i + 1} 发送BNB失败:`, error) // 出错时重置nonce await nonceManager.resetNonce() } } else { console.log(`✅ 账户 ${i + 1}: ${userWallet.address} - ${ethers.formatEther(balance)} BNB`) } } // 分发TestBNB(使用BasicERC20作为TestBNB)给所有测试账户 console.log("\n💰 向所有测试账户分发TestBNB...") // 检查前3个账户的余额(主要测试账户) console.log("\n📊 主要测试账户余额检查:") for (let i = 0; i < Math.max(3, testAccounts.length); i++) { const account = testAccounts[i] const userWallet = new ethers.Wallet(account.privateKey, provider) const usd1Balance = await mockUSD1.balanceOf(userWallet.address) const realBnbBalance = await provider.getBalance(userWallet.address) console.log(`账户 ${i + 1} (${userWallet.address}):`) console.log(` - USD1: ${ethers.formatEther(usd1Balance)}`) console.log(` - 真实BNB: ${ethers.formatEther(realBnbBalance)}`) } console.log("\n🎉 代币分发成功完成!") console.log("\n📋 总结:") console.log("- 总账户数:", testAccounts.length) console.log("- 每个账户USD1:", ethers.formatEther(usd1Amount)) console.log("- 每个账户真实BNB:", ethers.formatEther(bnbGasAmount)) console.log("- MockUSD1地址:", contractAddresses.mockUSD1) } // 导出main函数供多环境脚本调用 export { main } // 如果直接运行此脚本 if (require.main === module) { main() .then(() => process.exit(0)) .catch((error) => { console.error("❌ Error:", error) process.exit(1) }) }