123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- 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<number> {
- if (this.nonce === 0) {
- // 从网络获取当前nonce
- const currentNonce = await this.provider.getTransactionCount(this.address)
- this.nonce = currentNonce
- }
- return this.nonce++
- }
- async resetNonce(): Promise<void> {
- 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)
- })
- }
|