---
title: 'Solidity WTF 103 33 單元 空投合約'
lang: zh-tw
---
Solidity WTF 103 33 單元 空投合約
===
:::info
:date: 2024/10/11
:::
[TOC]
# 空投合約
空投在幣圈是一種營銷策略,項目方提供代幣給參與者,拿到空投的資格,需要完成項目方規定的任務,例如:
- 產品測試
- 分享推文或是官網
- 邀請朋友
項目方可以免費請人CX並得到初始用戶,用戶可以獲得一些酬勞,而`酬勞就是空投`。然而接收空投的人很多,項目方不可能一筆一筆轉帳。利用智能合約批量發放`ERC20`代幣,就是空投提升效率的辦法。
## 合約
### 空投數量
首先,你必須確保你的總代幣數量是大於等於(>=)空投數量的,所以你要先計算空投數量。
```javascript=
function getSum(uint256[] calldata _arr) public pure returns(uint sum){
for(uint i = 0; i < _arr.length; i++)
sum = sum + _arr[i];
}
```
### 轉帳
接下來你會需要把空投地址帶入,並且還有對應的空投數量。
> 在向多個地址轉帳代幣,需要事先授權,為何需要先授權?
> 因為他是屬於合約自動發布給其他用戶,如果未事先授權則會有安全隱患等問題。
>> 這邊的授權意思 -> 讓此合約能夠token(IERC20)指定的代幣,並且有規定數量。
```javascript=
/// @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");
// 利用transferFrom函数發送空投
for (uint8 i; i < _addresses.length; i++) {
token.transferFrom(msg.sender, _addresses[i], _amounts[i]);
}
}
```
### 參數
function有寫好三個參數,分別為_token、_address、_amounts,分別帶入的話會是:
```javascript=
// _token
0x5802016Bc9976C6f63D6170157adAeA1924586c1
// 這邊是自己的ERC20的代幣合約,因為他要聲明一個IERC20,故帶入。
// _addresses
["0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2", "0x5B38Da6a701c568545dCfcB03FcB875f56beddC4"]
// _amounts
[100, 200]
```
:::success
因為不可能自行一個一個發空投代幣給用戶,所以需要一個合約多地址的去發行。
:::