一、说明
针对代币的批量转账功能,目前主要有两种常用的方式:直接调用transfer方法实现批量转账和借助transferFrom和approve授权方式实现代币的批量转账。两种方式具体实现如下:
- 批量调用transfer方式的转账:该方式通过循环调用代币的transfer方法,从合约地址中转出代币到接收地址,转账之前需要校验合约地址中的代币数量大于批量转账的所有代币的总量。否则转账会失败。并且该功能需要限制接口的访问权限为onlyowner
- 通过调用transferFrom函数从发送者地址中代转账,批量转账之前需要执行approve操作,授权足够数量的代币到合约地址中。调用合约接口从发送者钱包地址中批量转出代币。
二、核心代码实现
- 直接调用代币的transfer方法的核心代码:
function multiTransfer_fixed(address[] calldata _recipients, uint256 _values, address _tokenAddress) public onlyOwner returns (bool) {
require(_recipients.length > 0, "Airdrop Error: min airdrop limit is 1 address");
require(_recipients.length < 2001,"Airdrop Error: max airdrop limit is 2000 addresses"); // to prevent overflow
IERC20 token = IERC20(_tokenAddress);
uint256 SCCC = _recipients.length.mul(_values);
require(token.balanceOf(address(this)) >= SCCC, "Airdrop Error: insufficient token");
for(uint i = 0; i < _recipients.length; i++){
token.transfer(_recipients[i], _values);
}
return true;
}
每次限制最大转账2000笔,直接从合约地址中划走代币到接收者地址中。
2. 通过transferFrom方式从发送者钱包地址中批量转账:
function multiTransfer_fixed_upgrade(address from, address[] calldata _recipients, address _tokenAddress, uint256 _values) public onlyOwner returns (bool) {
require(_recipients.length > 0, "Airdrop Error: min airdrop limit is 1 address");
require(_recipients.length < 2001,"Airdrop Error: max airdrop limit is 2000 addresses"); // to prevent overflow
//bytes4 id = bytes4(keccak256("transferFrom(address,address,uint256)"));
for (uint i = 0; i < _recipients.length; i++) {
(bool success, bytes memory returndata) = _tokenAddress.call(abi.encodeWithSignature("transferFrom(address,address,uint256)", from, _recipients[i], _values));
require(success && returndata.length > 0, "Airdrop Error: single address airdrop fail");
}
return true;
}
通过solidity中的call方法,直接操作地址进行批量转账。执行操作之前需要预先授权合约地址足够数量的代币,才能成功过调用transferFrom方法。
3. transferFrom批量转账功能整合到合约中的完整代码如下:
pragma solidity ^0.4.23;
contract Airdrop {
function transfer(address from, address caddress, address[] _tos, uint v) public returns (bool) {
require(_tos.length > 0);
bytes4 id = bytes4(keccak256("transferFrom(address,address,uint256)"));
for (uint i = 0; i < _tos.length; i++) {
require(caddress.call(id, from, _tos[i], v));
}
return true;
}
}
代码不复杂,最关键的一点是用到了 solidity 中对地址的操作,在合约中 call 另一个合约,首先得知道要调用的是哪一个函数,因为是批量转账,这里用 transferFrom 函数,为什么不用 transfer 呢?因为这里发起交易的主体是合约地址,而不是原来的账户地址,我们可以看看 transfer 函数和 transferFrom 函数有什么不同。
function transfer(address _recipient, uint256 _value) onlyPayloadSize(2 * 32) public {
require(balances[msg.sender] >= _value && _value > 0);
balances[msg.sender] -= _value;
balances[_recipient] += _value;
Transfer(msg.sender, _recipient, _value);
}
function transferFrom(address _from, address _to, uint256 _value) public {
require(balances[_from] >= _value && allowed[_from][msg.sender] >= _value && _value > 0);
balances[_to] += _value;
balances[_from] -= _value;
allowed[_from][msg.sender] -= _value;
Transfer(_from, _to, _value);
}
让合约实现代币转账首先需要做得是让合约得到操纵一定量代币的权利,可以看到transfer 函数首先检查地址的余额,意味着要让合约替你转账,你得先转给它一部分代币才行,但让合约直接拥有代币是不太安全的,而 transferFrom 就不同了,它检查的是授信额度,意思是你只需要先授信给合约它能操纵的代币数量,这样的好处是降低风险。
至此,完成transferFrom配合approve和直接transfer两种方式实现代币的批量转账功能所有操作流程。
pdf+视频币安智能链BSC发币教程及多模式组合合约源代码下载:
币安智能链BSC发币(合约部署、开源、锁仓、LP、参数配置、开发、故障处理、工具使用)教程下载:
多模式(燃烧、回流指定营销地址、分红本币及任意币种,邀请推广八代收益,LP加池分红、交易分红、复利分红、NFT分红、自动筑池、动态手续费、定时开盘、回购)组合合约源代码下载:
pdf+视频币安智能链BSC发币教程及多模式组合合约源代码下载地址:
添加VX或者telegram获取全程线上免费指导
评论前必须登录!
注册