如何在单笔交易中向多个地址发送代币?
单笔交易批量转账代币的实现方案
1. 优先使用合约内置的批量转账方法
如果你的代币合约已经实现了transferBatch或multiTransfer这类批量转账接口,可以直接调用,无需额外部署合约:
调用示例代码
web3.eth.requestAccounts().then(function(accounts){ const sender = accounts[0]; // 收款人地址数组和对应转账金额数组(金额需转成代币最小单位,比如wei) const recipients = ["0x123...", "0x456...", "0x789..."]; const amounts = [ web3.utils.toWei("1", "ether"), web3.utils.toWei("2", "ether"), web3.utils.toWei("0.5", "ether") ]; Contract.methods.transferBatch(recipients, amounts).send( {from: sender, gas: 200000} // 批量转账gas消耗更高,需根据实际收款人数调整 ).then(tx => { console.log("批量转账成功,交易哈希:", tx.transactionHash); }).catch(err => { console.error("转账失败:", err); }); });
2. 标准ERC20合约的批量转账方案
如果你的代币是标准ERC20(仅支持transfer/transferFrom),需要部署一个批量转账代理合约,通过这个合约在单笔交易内完成多地址转账:
批量转账代理合约(Solidity)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; contract BatchTransfer { function batchTransfer(IERC20 token, address[] calldata recipients, uint256[] calldata amounts) external { require(recipients.length == amounts.length, "长度不匹配"); // 计算总转账金额 uint256 total = 0; for (uint256 i = 0; i < amounts.length; i++) { total += amounts[i]; } // 从发送者处转入代币到代理合约(需提前授权) require(token.transferFrom(msg.sender, address(this), total), "转入代理合约失败"); // 向每个收款人分发代币 for (uint256 i = 0; i < recipients.length; i++) { require(token.transfer(recipients[i], amounts[i]), "分发代币失败"); } } }
前端调用代码
web3.eth.requestAccounts().then(async function(accounts){ const sender = accounts[0]; const tokenABI = [/* 你的ERC20合约ABI */]; const batchABI = [/* 批量转账合约ABI */]; const tokenAddr = "0x..."; // 代币合约地址 const batchAddr = "0x..."; // 批量转账合约地址 const tokenContract = new web3.eth.Contract(tokenABI, tokenAddr); const batchContract = new web3.eth.Contract(batchABI, batchAddr); const recipients = ["0x123...", "0x456...", "0x789..."]; const amounts = [ web3.utils.toWei("1", "ether"), web3.utils.toWei("2", "ether"), web3.utils.toWei("0.5", "ether") ]; const totalAmount = amounts.reduce((sum, amt) => sum.add(web3.utils.toBN(amt)), web3.utils.toBN("0")); // 第一步:给批量转账合约授权代币额度 await tokenContract.methods.approve(batchAddr, totalAmount).send({from: sender}); // 第二步:执行批量转账 batchContract.methods.batchTransfer(tokenAddr, recipients, amounts).send( {from: sender, gas: 300000} ).then(tx => { console.log("批量转账成功,交易哈希:", tx.transactionHash); }).catch(err => { console.error("转账失败:", err); }); });
关键注意点
- Gas调整:批量转账的gas消耗随收款人数增加而上升,需根据实际情况设置足够的gas上限,避免交易失败。
- 授权验证:使用代理合约时,必须确保授权的代币额度≥总转账金额,否则
transferFrom会失败。 - 安全审计:代理合约涉及资金操作,部署前务必做好安全检查,避免出现逻辑漏洞导致代币损失。
内容的提问来源于stack exchange,提问作者Ashwani Kashyap
相关产品推荐
相关产品推荐

