空投是幣圈中一種行銷策略,專案方將代幣免費發放給特定用戶群。為了拿到空投資格,使用者通常需要完成一些簡單的任務,例如測試產品、分享新聞、介紹朋友等。專案方透過空投可以獲得種子用戶,而用戶可以獲得一筆財富,兩全其美。 因為每次接收空投的用戶很多,所以項目方不可能一筆一筆的轉帳。利用智慧合約批量發放ERC20代幣,可顯著提高空投效率。
Airdrop空投合約邏輯非常簡單:利用循環,一筆交易將ERC20代幣發送給多個地址。合約中包含兩個函數
function getSum(uint256[] calldata _arr) public pure returns(uint sum){
for(uint i = 0; i < _arr.length; i++)
sum = sum + _arr[i];
}
/// @notice 向多個地址轉帳ERC20代幣,使用前需先授權
///
/// @param _token 轉帳的ERC20代幣地址
/// @param _addresses 空投位址數組
/// @param _amounts 代幣數量數組(每個地址的空投數量)
function multiTransferToken(
address _token,
address[] calldata _addresses,
uint256[] calldata _amounts
) external {
// 檢查:_addresses和_amounts數組的長度相等
require(_addresses.length == _amounts.length, "Lengths of Addresses and Amounts NOT EQUAL");
IERC20 token = IERC20(_token); // 聲明IERC合約變量
uint _amountSum = getSum(_amounts); // 計算空投代幣總量
// 檢查:授權代幣數量 >= 空投代幣總量
require(token.allowance(msg.sender, address(this)) >= _amountSum, "Need Approve ERC20 token");
// for循環,利用transferFrom函數發送空投
for (uint8 i; i < _addresses.length; i++) {
token.transferFrom(msg.sender, _addresses[i], _amounts[i]);
}
}
/// 向多個地址轉帳ETH
function multiTransferETH(
address payable[] calldata _addresses,
uint256[] calldata _amounts
) public payable {
// 檢查:_addresses和_amounts數組的長度相等
require(_addresses.length == _amounts.length, "Lengths of Addresses and Amounts NOT EQUAL");
uint _amountSum = getSum(_amounts); // 計算空投ETH總量
// 檢查轉入ETH等於空投總量
require(msg.value == _amountSum, "Transfer amount error");
// for循環,利用transfer函數發送ETH
for (uint256 i = 0; i < _addresses.length; i++) {
// 註解程式碼有Dos攻擊風險, 且transfer 也是不推薦寫法
// Dos攻擊具體參考 https://github.com/AmazingAng/WTF-Solidity/blob/main/S09_DoS/readme.md
// _addresses[i].transfer(_amounts[i]);
(bool success, ) = _addresses[i].call{value: _amounts[i]}("");
if (!success) {
failTransferList[_addresses[i]] = _amounts[i];
}
}
}