Airdrop合约
multiTransferETH():批量发送ETH,包含2个参数:
_addresses:接收空投的用户地址数组(address[]类型)
_amounts:空投数量数组,对应_addresses里每个地址的数量(uint[]类型)
multiTransferToken()函数:批量发送ERC20代币,包含3个参数:
_token:代币合约地址(address类型)
_addresses:接收空投的用户地址数组(address[]类型)
_amounts:空投数量数组,对应_addresses里每个地址的数量(uint[]类型)
批量转账
import {
ethers } from "ethers";
console.log("\n1. 创建HD钱包")
// 通过助记词生成HD钱包
const mnemonic = `air organ twist rule prison symptom jazz cheap rather dizzy verb glare jeans orbit weapon universe require tired sing casino business anxiety seminar hunt`
const hdNode = ethers.utils.HDNode.fromMnemonic(mnemonic)
console.log(hdNode);
console.log("\n2. 通过HD钱包派生20个钱包")
const numWallet = 20
// 派生路径:m / purpose' / coin_type' / account' / change / address_index
// 我们只需要切换最后一位address_index,就可以从hdNode派生出新钱包
let basePath = "m/44'/60'/0'/0";
let addresses = [];
for (let i = 0; i < numWallet; i++) {
let hdNodeNew = hdNode.derivePath(basePath + "/" + i);
let walletNew = new ethers.Wallet(hdNodeNew.privateKey);
addresses.push(walletNew.address);
}
console.log(addresses)
const amounts = Array(20).fill(ethers.utils.parseEther("0.0001"))
console.log(`发送数额:${
amounts}`)
const ALCHEMY_SEPOLIA_URL = '';
const provider = new ethers.providers.JsonRpcProvider(ALCHEMY_SEPOLIA_URL);
const privateKey = ''
const wallet = new ethers.Wallet(privateKey, provider)
// Airdrop的ABI
const abiAirdrop = [
"function multiTransferToken(address,address[],uint256[]) external",
"function multiTransferETH(address[],uint256[]) public payable",
];
// Airdrop合约地址(Sepolia测试网)
const addressAirdrop = '0x09db240f6F727CC5794709EB38130d775abF8961' // Airdrop Contract
// 声明Airdrop合约
const contractAirdrop = new ethers.Contract(addressAirdrop, abiAirdrop, wallet)
// WETH的ABI
const abiWETH = [
"function balanceOf(address) public view returns(uint)",
"function transfer(address, uint) public returns (bool)",
"function approve(address, uint256) public returns (bool)"
];
// WETH合约地址(Sepolia测试网)
const addressWETH = '0x7b79995e5f793A07Bc00c21412e50Ecae098E7f9' // WETH Contract
// 声明WETH合约
const contractWETH = new ethers.Contract(addressWETH, abiWETH, wallet)
console.log("\n3. 读取一个地址的ETH和WETH余额")
//读取WETH余额
const balanceWETH = await contractWETH.balanceOf(addresses[10])
console.log(`WETH持仓: ${
ethers.utils.formatEther(balanceWETH)}\n`)
//读取ETH余额
const balanceETH = await provider.getBalance(addresses[10])
console.log(`ETH持仓: ${
ethers.utils.formatEther(balanceETH)}\n`)
console.log("\n4. 调用multiTransferETH()函数,给每个钱包转 0.0001 ETH")
// 发起交易
const tx = await contractAirdrop.multiTransferETH(addresses, amounts, {
value: ethers.utils.parseEther("0.002")})
// 等待交易上链
await tx.wait()
// console.log(`交易详情:`)
// console.log(tx)
const balanceETH2 = await provider.getBalance(addresses[10])
console.log(`发送后该钱包ETH持仓: ${
ethers.utils.formatEther(balanceETH2)}\n`)
console.log("\n5. 调用multiTransferToken()函数,给每个钱包转 0.0001 WETH")
// 先approve WETH给Airdrop合约
const txApprove = await contractWETH.approve(addressAirdrop, ethers.utils.parseEther("1"))
await txApprove.wait()
// 发起交易
const tx2 = await contractAirdrop.multiTransferToken(addressWETH, addresses, amounts)
// 等待交易上链
await tx2.wait()
// console.log(`交易详情:`)
// console.log(tx2)
// 读取WETH余额
const balanceWETH2 = await contractWETH.balanceOf(addresses[10])
console.log(`发送后该钱包WETH持仓: ${
ethers.utils.formatEther(balanceWETH2)}\n`)