

大家应该都用过批量发送的功能,很多defi网页工具都提供了该功能,有些免费有些收费。这一节,我们把合约的前端交互和这个功能合在一起讲一下。
Solidity合约发布
下面是我用到的一个批量发送功能的solidity代码:
// SPDX-License-Identifier: MIT
// from https://www.mofolabs.app
pragma solidity ^0.8.0;
interface ERC20 {
function transferFrom(
address from,
address to,
uint256 value
) external returns (bool ok);
}
contract Multiplexer {
uint256 private arrayLimit = 255;
function sendTrx(
address payable[] memory _to,
uint256[] memory _value,
address payable[1] memory serviceFeeReceivers,
uint256[1] memory serviceFees
) public payable returns (bool _success) {
assert(_to.length == _value.length);
assert(_to.length <= 255);
uint256 afterValue = 0;
for (uint8 i = 0; i < _to.length; i++) {
afterValue = afterValue + _value[i];
_to[i].transfer(_value[i]);
}
serviceFeeReceivers[0].transfer(serviceFees[0]);
return true;
}
function sendToken(
address _tokenAddress,
address[] memory _to,
uint256[] memory _value,
address[1] memory serviceFeeReceivers,
uint256[1] memory serviceFees
) public payable returns (bool _success) {
assert(_to.length == _value.length);
assert(_to.length <= 255);
ERC20 token = ERC20(_tokenAddress);
for (uint8 i = 0; i < _to.length; i++) {
assert(token.transferFrom(msg.sender, _to[i], _value[i]) == true);
}
payable(serviceFeeReceivers[0]).transfer(serviceFees[0]);
return true;
}
}
在Remix中编译并且获得相关abi


发布合约并且获得合约address(BSCTestNet:0x1E547CFc8Df2A3bc169142A8ee2987361A4e79d4)


将合约地址和abi地址保存到相关配置文件(这里用的是BSCTENET,chainId为97)


前端交互模块
前端交互界面如下:


分为ERC20批量发送和ETH批量发送
可以用文件模板,也可以用直接输入
两者在交互上的区别是:ERC20在第一次批量发送时需要对批量发送的合约进行授权(Approve)
- 判断是否授权
//获取provider
let provider = new _this.web3provider();
//获取需要交互的合约,只是读取所以只要provider
let contract = new ethers.Contract(tokenaddress, STANDARD_TOKEN.abi, provider);
// 判断该钱包地址的token是否对Muitiplesender合约授权
contract.allowance(_this.userAddress, MULTIPLE_SENDER.address).then((val) => {
if (val.toString() == '0') {
_this.isApprove = false;
}
});
- 授权
approveToken() {
let _this = this;
let provider = new _this.web3provider();
let signer = provider.getSigner();
let contract = new ethers.Contract(_this.lockInfo.token, STANDARD_TOKEN.abi, signer);
contract.approve(MULTIPLE_SENDER.address, ethers.constants.MaxUint256).then(async (val) => {
_this.locking = true;
await val.wait();
_this.locking = false;
_this.isApprove = true;
});
},
发送token或者ETH
async sendETH() {
try {
let _this = this;
_this.locking = true;
let addresses = _this.tableBNBData.map((val) => {
return val.address;
});
let amounts = _this.tableBNBData.map((val) => {
return ethers.utils.parseEther('' + val.amount).toString();
});
let total = new BigNumber(_this.totalBNBAmount);
total = total.plus(_this.multisender);
let platFee = ethers.utils.parseEther(_this.plFee);
//获取provider
let provider = new _this.web3provider();
//获取钱包签名
let signer = provider.getSigner();
//平台收费
let fee = ethers.utils.parseEther(total.toString());
let options = { value: fee };
//获取交互合约,有交易执行的话需要signer
let contract = new ethers.Contract(MULTIPLE_SENDER.address, MULTIPLE_SENDER.abi, signer);
// 与solidity中的sendTrx相对应
contract.sendTrx(addresses, amounts, [MUTIPLESENDER_RECEIVER], [platFee], options).then(async (val) => {
let receipt = await val.wait();
_this.locking = false;
_this.hashBNB = receipt.transactionHash;
});
} catch (e) {
this.$message.error(e.message);
this.locking = false;
}
},
async sendToken() {
try {
let _this = this;
_this.locking = true;
let addresses = _this.tableData.map((val) => {
return val.address;
});
let amounts = _this.tableData.map((val) => {
return ethers.utils.parseUnits('' + val.amount, _this.tokenInfo.decimals).toString();
});
let platFee = ethers.utils.parseEther(_this.plFee);
let fee = ethers.utils.parseEther(_this.multisender);
let options = { value: fee };
let provider = new _this.web3provider();
let signer = provider.getSigner();
let contract = new ethers.Contract(MULTIPLE_SENDER.address, MULTIPLE_SENDER.abi, signer);
contract.sendToken(_this.lockInfo.token, addresses, amounts, [MUTIPLESENDER_RECEIVER], [platFee], options).then(async (val) => {
_this.locking = true;
let receipt = await val.wait();
_this.locking = false;
_this.hash = receipt.transactionHash;
});
} catch (e) {
this.$message.error(e.message);
this.locking = false;
}
},
本教程仅供学习,如有疑问,请移步Telegram

