前几天fcoin的空投把eth堵得不成样,看见好几个竟然是一个个地transfer转账,但是实际上如果用合约实现批量转账,不管是成功率还是效率都会高很多,还省gas。
本文讲解如何用合约实现批量转账
既然是用合约实现,首先先写合约
pragma solidity ^0.4.0;
contract demo{
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++){
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就不同了,它检查的是授信额度,意思是你只需要先授信给合约它能操纵的代币数量,这样的好处是降低风险。
我们用remix在测试网络上部署合约,同时还需要部署一个erc20标准的代币合约(发行erc20代币参考)
接下来为大家演示一下空投过程,首先授信,我们在_spender授信目标处填上空投合约的地址,在value里填上数量
授信完成后,可以调用allowance查看当前授信额度,关于授信的解释:
approve、transferFrom及allowance解释:
账户A有1000个ETH,想允许B账户随意调用100个ETH。A账户按照以下形式调用approve函数approve(B,100)
。当B账户想用这100个ETH中的10个ETH给C账户时,则调用transferFrom(A, C, 10)
。这时调用allowance(A, B)
可以查看B账户还能够调用A账户多少个token。
接下来是重头戏,真正的批量转账
参数解释:from是账户地址(授信主体的账户),caddress是代币合约地址,_tos是转账目标地址(数组),v是每个地址转账的数量
meta mask发送交易,gaslimit多填点
成功以后在etherscan上查看
准备的地址不多,但是可以看见实现了一笔交易多个转账,也就是批量转账了,大家可以根据自己的需求实现每个地址不同数量的批量转账,或者批量转账以太坊也行只要你有钱。真正空投的时候地址很多,但是因为gaslimit限制建议大家每次转不超过100个地址,关于gaslimit可以参考在以太坊上存图片。