热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

给合约升级一下

给合约升级一下-上回的空投合约非常的简单就一个负责转账的函数:Airdrop.solSPDX-License-Identifier:MITpragmasolidity^0.8.4

上回的空投合约非常的简单就一个负责转账的函数:
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.最后发起空投,查看一下他们是否收到了奖励。

下面是他们账户的截图:

最后

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


推荐阅读
  • vue使用
    关键词: ... [详细]
  • JDK源码学习之HashTable(附带面试题)的学习笔记
    本文介绍了JDK源码学习之HashTable(附带面试题)的学习笔记,包括HashTable的定义、数据类型、与HashMap的关系和区别。文章提供了干货,并附带了其他相关主题的学习笔记。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • IhaveconfiguredanactionforaremotenotificationwhenitarrivestomyiOsapp.Iwanttwodiff ... [详细]
  • 本文介绍了[从头学数学]中第101节关于比例的相关问题的研究和修炼过程。主要内容包括[机器小伟]和[工程师阿伟]一起研究比例的相关问题,并给出了一个求比例的函数scale的实现。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • 本文介绍了在Vue项目中如何结合Element UI解决连续上传多张图片及图片编辑的问题。作者强调了在编码前要明确需求和所需要的结果,并详细描述了自己的代码实现过程。 ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • 本文介绍了如何使用动态尺寸巧妙地将R中的数组子集化。作者通过解释数组的三个维度以及第三个维度的长度可变性,提出了一种周期性子集化数组的方法,并举例说明了如何创建第二个数组。这个方法对于制作模拟模型非常有用。 ... [详细]
  • 【shell】网络处理:判断IP是否在网段、两个ip是否同网段、IP地址范围、网段包含关系
    本文介绍了使用shell脚本判断IP是否在同一网段、判断IP地址是否在某个范围内、计算IP地址范围、判断网段之间的包含关系的方法和原理。通过对IP和掩码进行与计算,可以判断两个IP是否在同一网段。同时,还提供了一段用于验证IP地址的正则表达式和判断特殊IP地址的方法。 ... [详细]
  • 模板引擎StringTemplate的使用方法和特点
    本文介绍了模板引擎StringTemplate的使用方法和特点,包括强制Model和View的分离、Lazy-Evaluation、Recursive enable等。同时,还介绍了StringTemplate语法中的属性和普通字符的使用方法,并提供了向模板填充属性的示例代码。 ... [详细]
author-avatar
巡山小妖
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有