# Solidity极简入门: 33. 空投合约

By [0xAA](https://paragraph.com/@wtfacademy) · 2022-06-29

---

我最近在重新学solidity，巩固一下细节，也写一个“Solidity极简入门”，供小白们使用（编程大佬可以另找教程），每周更新1-3讲。

欢迎关注我的推特：[@0xAA\_Science](https://twitter.com/0xAA_Science)

欢迎加入WTF科学家社区，内有加微信群方法：[链接](https://discord.gg/5akcruXrsk)

所有代码和教程开源在github（1024个star发课程认证，2048个star发社群NFT）: [github.com/AmazingAng/WTFSolidity](https://github.com/AmazingAng/WTFSolidity)

* * *

在币圈，最开心的一件事就是领空投，空手条白狼。这一讲，我们将学习如何使用使用智能合约空投`ERC20`代币。

空投 Airdrop
----------

空投是币圈中一种营销策略，项目方将代币免费发放给特定用户群体。为了拿到空投资格，用户通常需要完成一些简单的任务，如测试产品、分享新闻、介绍朋友等。项目方通过空投可以获得种子用户，而用户可以获得一笔财富，两全其美。

因为每次接收空头的用户很多，项目方不可能一笔一笔的转账。利用智能合约批量发放`ERC20`代币，可以显著提高空投效率。

### 空投代币合约

`Airdrop`空投合约逻辑非常简单：利用循环，一笔交易将`ERC20`代币发送给多个地址。合约中包含两个函数

*   `getSum()`函数：返回`uint`数组的和。
    

        // 数组求和函数
        function getSum(uint256[] calldata _arr) public pure returns(uint sum)
        {
            for(uint i = 0; i < _arr.length; i++)
                sum = sum + _arr[i];
        }
    

*   `multiTransferToken()`函数：发送`ERC20`代币空投，包含三个参数：
    
    *   `_token`：代币合约地址（`address`类型）
        
    *   `_addresses`：接收空投的用户地址数组（`address[]`类型）
        
    *   `_amounts`：空投数量数组，对应`_addresses`里每个地址的数量（`uint[]`类型）
        
    
    该函数有两个检查：第一个`require`检查了`_addresses`和`_amounts`两个数组长度是否相等；第二个`require`检查了空投合约的授权额度大于要空投的代币数量总和。
    

    /// @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]);
            }
        }
    

### 空投实践

1 部署ERC20代币合约，并给自己mint 10000 单位代币。

![部署ERC20](https://storage.googleapis.com/papyrus_images/c13dd4e403a6196a33f7adf1e1b3cd98293cbafb847258c9ce9945f6a71d1e2d.png)

部署ERC20

2 部署`Airdrop`空投合约。

![部署Airdrop](https://storage.googleapis.com/papyrus_images/9869b6738b3613cd3994cd8ce664ca9e9b6357d32a8512970b41d000850edb94.png)

部署Airdrop

3 利用`ERC20`代币合约中的`approve()`函数，给`Airdrop`空投合约授权10000 单位代币。

![授权](https://storage.googleapis.com/papyrus_images/70bf961f7078651f9571c604f8bcaff50bc89641b0c5bc26a861da109ff4a4c7.png)

授权

4 执行`Airdrop`合约的`multiTransferToken()`函数进行空投， `_token`填`ERC20`代币地址，`_addresses`和`_amounts`按照以下填写

    // _addresses填写
    ["0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2", "0x5B38Da6a701c568545dCfcB03FcB875f56beddC4"]
    
    // _amounts填写
    [100, 200]
    

![执行空投](https://storage.googleapis.com/papyrus_images/fa14749c8940b196d15594fee10175b938c4db1aa850da362c17ee6e525eec98.png)

执行空投

5 利用`ERC20`合约的`balanceOf()`函数查询上面用户地址的代币余额，成功变为`100`和`200`，空投成功！

![空投成功！](https://storage.googleapis.com/papyrus_images/a18d22a4df0a5e22db22c6fdf8b02c2f48e1414e46ff9f0d71475664d09b90f9.png)

空投成功！

总结
--

这一讲，我们介绍了如何使用`solidity`写`ERC20`代币空投合约，极大增加空投效率。我撸空投收获最大的一次是`ENS`空投，你们呢？

---

*Originally published on [0xAA](https://paragraph.com/@wtfacademy/solidity-33)*
