给合约升级一下

最近我在学习空投合约,学习资料中的合约样例非常的简单,就一个负责转账的函数,下面是合约代码:
Airdrop.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "./IERC20.sol"; //import IERC20
contract Airdrop {
    function multiTransferToken(
        address _token,
        address[] calldata _addresses
        ) external {
        IERC20 token = IERC20(_token);
        uint _amountSum = _addresses.length * 100;
        require(token.allowance(msg.sender, address(this)) > _amountSum, "Need Approve ERC20 token");
        for (uint256 i; i < _addresses.length; i++) {
            token.transferFrom(msg.sender, _addresses[i], 100)
        }
    }
}

通过一番学习,现在我要来完善一下它,给它升级一下。

升级合约

首先,来分析一下需要完善的点:
1.发起空投得自己输入账户地址数组,如果数量多了,会很麻烦;
解决思路:既然是空投合约,那么就应该是给主动参与活动的账户都投递空投,那就需要设置一个join函数让大家主动加入活动,获得奖励。
2.空投的代币数量固定,不够方便;
解决思路:给每个参与空投的账户设置一个空投数量,用一个数组存储它们,还得能由合约拥有者进行设置,这样就更灵活了。

那么首先,要定义一个数组来存储参与空投的账户地址和它们对应的空投数量,在这里mapping就是很好的选择了:

mapping(address => uint) private _addresses;

之后,写一个参加活动的函数:

function join() public {
        payable(msg.sender).transfer(0);
        _add(msg.sender);
    }

function _add(address _address) private {
        require(_addresses[_address] == 0,"This address has already participated in the activity!");
        _addresses[_address] = 100;
        _addressArr.push(_address);
        _token.approve(_address,_addresses[_address]);
    }

接下来,我们写一个设置空投数量的函数:

function setAirdropNumber(address _address, unit num) public {
		require(msg.sender == owner,"you are not owner!")
		_addresses[_address] = num;
}

发起空投的函数也需要修改一番:

function multiTransferToken() external {
        uint _amountSum = _getSum(_addressArr);
        require(_token.balanceOf(address(this)) >= _amountSum, "Need enough ERC20 token");
        for (uint i; i < _addressArr.length; i++) {
            _token.transfer(_addressArr[i], _addresses[_addressArr[i]]);
        }
    }
function _getSum(address[] memory _arr) private view returns(uint sum){
        sum = 0;
        for(uint i = 0; i < _arr.length; i++){
            sum = sum + _addresses[_arr[i]];
        }
    }

根据以上的代码和需求,我对代码进一步进行完善,最终的代码就出现了:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "./IERC20.sol"; //import IERC20
/// @notice 向多个地址转账ERC20代币
contract Airdrop {
    address private _owner;
    IERC20 private _token;
    mapping(address => uint) private _addresses;
    address[] private _addressArr;

    constructor(address tokenAddress) {
        _owner = msg.sender;
        _token = IERC20(tokenAddress);
    }
    function join() public {
        payable(msg.sender).transfer(0);
        _add(msg.sender);
    }

    function _add(address _address) private {
        require(_addresses[_address] == 0,"This address has already participated in the activity!");
        _addresses[_address] = 100 * (10 ** 18);
        _addressArr.push(_address);
        _token.approve(_address,_addresses[_address]);
    }
    function setAirdropNumber(address _address, uint num) public {
        require(_owner == msg.sender, "you are not owner!");
        _addresses[_address] = num;
        _token.approve(_address,_addresses[_address]);
    }
    function multiTransferToken() external {
        uint _amountSum = _getSum(_addressArr);
        require(_token.balanceOf(address(this)) >= _amountSum, "Need enough ERC20 token");
        for (uint i; i < _addressArr.length; i++) {
            _token.transfer(_addressArr[i], _addresses[_addressArr[i]]);
        }
    }
    function _getSum(address[] memory _arr) private view returns(uint sum){
        sum = 0;
        for(uint i = 0; i < _arr.length; i++){
            sum = sum + _addresses[_arr[i]];
        }
    }
}

现在,将新合约部署上链,测试一下吧。

测试合约

1.将之前的代币设置为合约的默认奖励代币;
在这里插入图片描述

2.在CHAINPIP社区中先将加入活动的功能开放出来,这样所有想加入的朋友都可以加入活动;
在这里插入图片描述

3.现在使用俩个测试账户来加入活动:
地址1:0x754EcB8939e806b365f59aeF9Eadf0cd12b84831
地址2:0x0A67e0A87b9E436808253E3a6EdA2ce333996ccB
在这里插入图片描述

4.之后我给其中一个账户修改一下空投的数量,将数量修改为300:
地址:0x754EcB8939e806b365f59aeF9Eadf0cd12b84831
在这里插入图片描述

5.最后发起空投,查看一下他们是否收到了奖励。
在这里插入图片描述

下面是他们账户的截图:
在这里插入图片描述
在这里插入图片描述

最后
现在这个合约与之前相比,有了很大的改进,让大家更加方便地加入活动。但是合约目前都只是考虑功能方面,在安全性方面还有不足,所以还需要继续学习新知识来更好地完善它。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值