批量轉賬的原理
我們將講解三種空投的實現方式,前兩中都是在重新部署一個空投合約,第三種則是在代幣程式碼部署之前就寫好空投程式碼
有不少的代幣已經在以太坊上線部署,一旦上線之後是不能修改程式碼的,所以這些代幣要想實現空投就必須重新部署一個空投合約。利用空投合約進行轉賬。這種方式主要用到了ERC20標準中的兩個函式
approve: 此函式的呼叫方授權給定的地址可以從其地址中提款。
transferFrom: 該函式允許智慧合約自動執行轉賬流程並代表所有者傳送給定數量的通證。
複製程式碼
第一種方式
我們可以利用approve
函式給空投合約地址給與許可權,讓他可以呼叫一個地址中的代幣,然後迴圈呼叫空投合約中的transferFrom
進行批量轉賬
先寫一個簡單的空投合約程式碼
pragma solidity ^0.4.0;
contract Airdrop {
function batch(address tokenAddr, address []toAddr, uint256 []value) returns (bool){
require(toAddr.length == value.length && toAddr.length >= 1);
bytes4 fID= bytes4(keccak256("transferFrom(address,address,uint256)"));
for(uint256 i = 0 ; i < toAddr.length; i++){
if(!tokenAddr.call(fID, msg.sender, toAddr[i], value[i])) { revert(); }
}
}
}
複製程式碼
定義了batch
函式進行空投,會接受三個引數:
- 合約地址
- 接受地址列表
- 空投值的列表,和地址列表一一對應
可以看到在for迴圈當中利用transferFrom
函式進行批量轉賬
按照之前部署合約的步驟進行部署,在命令列中輸入airdrop
如果看到上圖,就說明你部署成功啦!
接下來就利用該合約進行空投,首先需要利用approve
給與空投合約一定的許可權
對上面的步驟簡單講解一下,首先我們檢視空投合約地址可以呼叫的數量為0
allowance
返回空投合約地址可以調動一個地址代幣的數量
對地址進行解鎖,並利用approve
賦予許可權,在挖礦之後繼續檢視,發現空投合約可以呼叫eth.accounts[0]
這個地址當中的20個代幣
給予許可權之後,我們就開始空投!
airdrop.batch.sendTransaction('0x6cbde372b5d3ceeee74fd56a6681eea2c3a4e94c',['0xd1d4e4a5ea685295b22d9fbe68b0cc6a8736ecf9','0xa90cf1c04ad3e96f081b599db2a7c12251ada066','0xc7e452aa3230d3699852687f7deb3c160d6ebab0','0x3e9197eb3faa278d455a35d4e9f0bc529dd5732f','0xb2dd757d40ea4b10df06e9c91e62109b82e0420b'],[1,2,3,2,1],{gas:300000})
複製程式碼
會有人發現上面的命令不是直接執行batch
方法,而是呼叫了sendTransactoin
,這是因為我在命令列下,預設的gas很低,但是這筆交易的資料很多,所以會因為gas用光而失敗,不直接呼叫batch
是為了最後的引數gas:300000
把gas設定的高一點。當然你直接呼叫batch
方法也是可以的,但是不要最後的{gas:300000}
從上面可以看到批量轉賬完成
第二種方式
第一種方式需要我們利用approve
給合約地址給予一定的許可權,但是如果我們把合約地址當成一個賬戶地址,給他轉一些代幣,那麼空投合約就可以用自己地址當中的幣進行轉賬了。
先寫一個可以實現這種方式的合約程式碼
pragma solidity ^0.4.18;
contract Ownable {
address public owner;
function Ownable() public {
owner = msg.sender;
}
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
}
interface Token {
function balanceOf(address _owner) public constant returns (uint256 );
function transfer(address _to, uint256 _value) public ;
event Transfer(address indexed _from, address indexed _to, uint256 _value);
}
contract Airdropper is Ownable {
function AirTransfer(address[] _recipients, uint[] _values, address _tokenAddress) onlyOwner public returns (bool) {
require(_recipients.length > 0);
Token token = Token(_tokenAddress);
for(uint j = 0; j < _recipients.length; j++){
token.transfer(_recipients[j], _values[j]);
}
return true;
}
}
複製程式碼
從程式碼中可以看到我們是利用合約地址當中的代幣進行交易的,按照之前部署代幣的步驟我們進行部署
部署成功之後,向空投合約轉一些代幣,然後呼叫空投合約的方法進行空投,實施的步驟和第一種方式大同小異,就不在贅述了,具體看下圖
第三種方式
前面兩種方式都是在合約外部在重新部署一個合約用於空投,第三種方式則是在合約中就實現空投,實現的思路其實和之前的方法一樣,只不過是集合到了合約當中
將下面的程式碼加到合約當中
function batch(address []toAddr, uint256 []value) returns (bool){
require(toAddr.length == value.length && toAddr.length >= 1);
for(uint256 i = 0 ; i < toAddr.length; i++){
transfer(toAddr[i], value[i]);
}
}
複製程式碼
按照之前的步驟部署到geth私有鏈中,檢視合約
可以發現,現在的合約當中已經有了batch
方法了,然後進行交易就可以了
空投合約的三種方式就實現了,其實原理都很簡單