Solidity学习之路 - 一步一步写一个空投合约

一起学:以太坊智能合约开发 课程介绍 无论在科技圈还是金融圈,“区块链”俨然成了最热的词汇。2016年,区块链写入了国家的十三五规划中;2017年,央行基于区块链技术的数字票据交易平台测试成功;同年,工信部发布了首个区块链参考架构标准。
经过2017年如火如荼的投资盛宴,区块链开始逐渐走向应用落地,业内都在积极探索使用场景。如金融领域的资产贸易、支付系统、金融服务,其他领域的电子商务、社交通讯、游戏娱乐等等。同时,BAT、迅... 阅读详情
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

contract Airdropper {
    using SafeERC20 for IERC20;

    address private owner;
    uint256 public airdropPerAmount; // 每人每次可以领取的空投数量
    uint256 public airdropTotalAmount; // 每人可以领取的空投总数
    uint256 public airdropTerm; // 多久可以领取一次(单位s),未设置则每人只能领一次
    uint256 public airdropStartTime; // 空投开始时间(时间戳)
    uint256 public airdropDeadline; // 空投截止时间(时间戳)
    address public tokenAddress; // 空投token地址
    mapping(address => uint256) public airdropRecord; // 每个人空投领取总额
    mapping(address => uint256) public airdropTimeRecord; // 最后一次领取空投时间

    // 发布合约时需传入5个参数,注意精度问题
    constructor(uint256 _airdropPerAmount, uint256 _airdropTotalAmount, uint256 _airdropTerm, uint256 _airdropStartTime, uint256 _airdropDeadline) {
        owner = msg.sender;
        airdropPerAmount = _airdropPerAmount;
        airdropTotalAmount = _airdropTotalAmount;
        airdropTerm = _airdropTerm;
        airdropStartTime = _airdropStartTime;
        airdropDeadline = _airdropDeadline;
    }

    // 批量发放空投,dests和values两个数组长度若相等,则给不同地址发放对应数量token,如果values只有一个元素,则每个地址发放等量token
    function doAirdrop(address[] memory dests, uint256[] memory values) external virtual returns (uint256) {
        // 批量发放一般为官方操作,不受时间、领取额度等以上各种条件限制
        require(msg.sender == owner, 'Airdropper: forbidden');
        require(tokenAddress != address(0), 'Airdropper: address not zero');
        uint256 i = 0;
        while (i < dests.length) {
            uint sendAmount = values.length == 1 ? values[0] : values[i];
            // 判断当前合约中剩余token是否够发放数量,如果不够则结束发放并返回已发放的最后一个索引
            if(ERC20(tokenAddress).balanceOf(address(this)) < sendAmount){
                break;
            }
            // 接收地址不为0,发放数量不为0,则执行发放
            if(dests[i] != address(0) && sendAmount > 0){
                IERC20(tokenAddress).safeTransfer(dests[i], sendAmount);
            }
            
            i++;
        }
        return i;
    }

    // 个人领取空投
    function getAirdrop() external virtual returns(bool){
        // token地址不能为0地址
        require(tokenAddress != address(0), 'Airdropper: address not zero');
        // 每人每次可以领取的空投数量要大于0
        require(airdropPerAmount > 0, 'Airdropper: no parameter set');
        // 当前时间要大于空投开始时间
        require(block.timestamp >= airdropStartTime, 'Airdropper: not started');
        if(airdropTotalAmount > 0){
            // 如果设置了 每人可以领取的空投总数 这个参数,则验证已领取数量要小于这个总数
            require(airdropRecord[msg.sender] < airdropTotalAmount, 'Airdropper: total amount limit');
        }
        if (airdropTerm > 0) {
            // 如果设置了领取周期参数,则验证当前时间减去上次领取时间大于这个周期
            require(block.timestamp - airdropTimeRecord[msg.sender] > airdropTerm , 'Airdropper: term limit');
        } else {
            // 如果没有设置周期参数,则验证没有领取过可以领取,只能领1次
            require(airdropRecord[msg.sender] == 0, 'Airdropper: you have already received');
        }
        if (airdropDeadline > 0) {
            // 如果设置了空投截止时间,则验证当前时间小于截止时间
            require(airdropDeadline > block.timestamp, 'Airdropper: deadline');
        }
        // 验证当前合约token数量够发放数量
        require(ERC20(tokenAddress).balanceOf(address(this)) >= airdropPerAmount, 'Airdropper: insufficient assets');
        // 执行发放
        IERC20(tokenAddress).safeTransfer(msg.sender, airdropPerAmount);
        // 累计领取总数
        airdropRecord[msg.sender] += airdropPerAmount;
        // 记录最后领取时间
        airdropTimeRecord[msg.sender] = block.timestamp;

        return true;
    }

    // 充入token
    function recharge(address _tokenAddress, uint256 _amount) external virtual returns(bool) {
        require(msg.sender == owner, 'Airdropper: forbidden');
        require(_tokenAddress != address(0), 'Airdropper: forbidden');
        if(tokenAddress == address(0)){
            // 第一次充入,配置token地址
            tokenAddress = _tokenAddress;
        } else {
            // 否则验证充入的token和配置的地址一致
            require(_tokenAddress == tokenAddress, 'Airdropper: Error token address');
        }
        // 执行充入token
        IERC20(tokenAddress).safeTransferFrom(msg.sender, address(this), _amount);

        return true;
    }

    // 提出剩余token
    function withdraw() external virtual returns(bool) {
        require(msg.sender == owner, 'Airdropper: forbidden');
        require(tokenAddress != address(0), 'Airdropper: address not zero');
        // 将剩余token全部转给合约发布者
        IERC20(tokenAddress).safeTransfer(owner, ERC20(tokenAddress).balanceOf(address(this)));
        tokenAddress = address(0); // 重置token地址

        return true;
    }

    /**
     * 以下是配置各个参数的接口,只有合约发布者可以调用
     */
    function setPerAmount(uint256 _airdropPerAmount) external virtual returns(bool) {
        require(msg.sender == owner, 'Airdropper: forbidden');
        airdropPerAmount = _airdropPerAmount;

        return true;
    }

    function setTotalAmount(uint256 _airdropTotalAmount) external virtual returns(bool) {
        require(msg.sender == owner, 'Airdropper: forbidden');
        airdropTotalAmount = _airdropTotalAmount;

        return true;
    }

    function setTerm(uint256 _airdropTerm) external virtual returns(bool) {
        require(msg.sender == owner, 'Airdropper: forbidden');
        airdropTerm = _airdropTerm;

        return true;
    }

    function setStartTime(uint256 _airdropStartTime) external virtual returns(bool) {
        require(msg.sender == owner, 'Airdropper: forbidden');
        airdropStartTime = _airdropStartTime;

        return true;
    }

    function setDeadline(uint256 _airdropDeadline) external virtual returns(bool) {
        require(msg.sender == owner, 'Airdropper: forbidden');
        airdropDeadline = _airdropDeadline;

        return true;
    }

}

这是一个经过实践的空投合约,在bsc和matic可以直接使用,在trc上问题应该也不大。很高兴分享给大家。在一些审计比较严格的情况下会报warning,每个函数都要有Event,自己加上就行。提示词就略过吧,实在懒得翻译,用的时候自己换一个自己喜欢的就好。

后续还会不断发布各类经过审计且完整可用的合约模板。现在正在整理过往项目,准备开发一个通用的Dapp快速开发框架。

加关注,不迷路,很开心和大家一起交流学习心得。

智能合约Solidity开发课视频教程(理论+实战+现实项目开发案例)2022年最新最全面 2022年最新最全面的智能合约Solidity开发课,从入门到精通。详细讲解:#区块链、#智能合约#Solidity、#以太坊、#加密货币、#NFT、#元宇宙,#底层结构与商业意图,避坑而从中获利!区块链智能合约Solidity开发课视频教程(理论+实战+现实项目开发案例)在学习课程过程中,我们还会进行实际的项目开发和案例分析。学完课程,你将拥有扎实的基础,独立开发后台智能合约。从底层EVM到高级应用,熟悉其中工作原理。课程由浅入深,从易到难,通俗易懂。从基本到复杂应用的场景。DAO治理等.... 阅读详情

相关推荐

Web3.0入门指南:区块链、智能合约与加密货币实践

Web3.0作为下一代互联网技术,基于区块链、智能合约和加密货币等核心技术,实现了去中心化的数据所有权和控制权。区块链作为其基础架构,通过分布式账本技术确保无需信任第三方的价值转移,而智能合约则自动化执行商业逻辑,广泛应用于DeFi、NFT和DAO等领域。加密货币钱包不仅是数字资产的存储工具,更是用户在Web3世界的身份凭证。对于开发者而言,掌握Solidity语言和智能合约开发工具链是进入Web3生态的关键。无论是非技术用户通过NFT和DeFi参与,还是开发者构建去中心化应用,Web3.0都提供了丰富的应

huqiyes的专栏 736

solidity实现智能合约教程(3)-空投合约

solidity实现智能合约教程(3)-空投合约,ERC1155,ERC721,ERC20,空投合约,批量转账合约

路漫漫其修远兮 吾将上下而求索 6390

Web3 开发者进阶学习图谱

【Web3开发者成长指南】 🚀 技术进阶:分三阶段掌握Web3开发,从Solidity基础到多链开发(L2、ZK技术),再到安全审计等高级方向,配套精选学习资源。 💻 远程兼职:推荐Gitcoin、Dework等平台,强调链上项目展示和GitHub活跃度,提供简历优化和面试演示技巧。 💰 空投收益:列出2024潜力项目(如zkSync、Starknet),提供任务追踪模板和工具推荐,建议每周1小时交互+部署合约。 ⏳ 持续策略:每周分配技术贡献、空投交互、项目开发及社交运营时间,打造被动收益循环。 (

战族狼魂的博客 1176

《我学区块链》—— 三十六、以太坊批量转账(空投)节省费用

三十五、智能合约收发 ETH 详解 前段时间 fcoin 的空投把 eth 堵得不成样,看见好几个空投竟然是一个个地 transfer转账,但是实际上如果用合约实现批量转账,不管是成功率还是效率都会高很多,还省 gas。 整个过程的模型如下: ![airdrop-construct](https://img-blog.csdnimg.cn/20181030143518379.png?x-oss-p...

xuguangyuansh的博客 4879

智能合约安全:整型溢出漏洞原理、攻击场景与防御实践

在计算机科学中,整型溢出是当算术运算结果超出数据类型所能表示范围时发生的现象,其原理源于计算机底层对固定位宽数据的处理机制。这一基础概念在区块链与智能合约开发中具有极高的技术价值,因为以太坊虚拟机(EVM)中,代码直接管理着数字资产,运算错误会导致不可逆的资产损失。整型溢出漏洞隐蔽性强,常出现在代币转账、数量计算和时间锁定等核心业务逻辑中,是DeFi与智能合约安全领域的常见高危漏洞。理解其原理并掌握SafeMath库应用、编译器内置检查等防御手段,是构建稳健区块链应用的关键。本文通过剖析EVM运算机制与经典

weixin_33912638的博客 385

智能合约入门实战:用Solidity开发任务积分系统并部署调用

区块链技术中的智能合约常被视作玄妙难懂,其本质是一段部署在去中心化网络上的自动执行代码,规则公开且不可篡改。Solidity作为以太坊生态最主流的合约语言,通过状态变量、映射、修饰器等机制,将传统业务逻辑转化为链上可信规则。从自动售货机的类比出发,智能合约实现了条件满足即执行的自动化流程,在积分系统、自动分账、供应链溯源等场景中具有广泛应用价值。本文以一个可运行的任务积分系统为例,完整演示了从合约设计、Solidity源码编写、Ganache本地链部署到ethers.js脚本调用的全过程,并总结了权限校验、

weixin_33095355的博客 236

Solidity - 空投

所谓空投,就是作为项目方,在项目的首发阶段为了做一些运营活动活跃用户,开发新用户,在初期给用户空投项目方的代币,或者ETH的行为。现在,我们来调用空投的方法。第二份drop合约需求是实现可添加不同的代币合约地址,之后调用方法可以一次性给用户分发不同的代币,这就避免了我们在分发代币的时候要一个个的去部署代币合约然后去进行分发。接着,我们部署Airdrop合约,并触发enter方法给合约转ETH用于空投,我在这里enter了三次,并在代币合约给Airdrop合约授权允许Airdrop合约从代币合约转账。

qq_42908175的博客 830

Sparkle-Airdrop:基于以太坊的Sparkle空投合约

Sparkle-Airdrop:基于以太坊的Sparkle空投合约

ERC20的创建及合约之间的调用(合约调用合约)

ERC20的创建,合约与合约之间的调用(合约调用合约)

m0_37298500的博客 2043

multisender:令牌Multisender Dapp智能合约。 空投令牌。 批量发送ERC20,ETH,以太坊令牌。 在几笔交易中发送数千笔转帐。 与一一发送相比,它可以帮助用户节省更多的发送费用和时间

问题: 以前在以太坊网络中,需要额外的工具才能一次传输许多ERC20令牌。 许多人仍然手动执行此操作,一次完成一次事务。 该过程很耗时并且容易出错。 解: 该Dapp允许用户以非常有效的方式发送成千上万个令牌传输,方法是将每个Ethereum交易中的145个令牌传输分组为一组。 通过自动生成到MetaMask的交易,这种自动化节省了时间。 最后,该工具允许用户通过将其私钥的信任委托给安全的MetaMask钱包来维护其帐户的安全性。 如何使用: 安装 。 确保您在MetaMask中有一个具有令牌余额的帐户。 确保您的MetaMask指向您要使用的网络。 确保您的MetaMask帐户已

如何在 Ubuntu 24.04 或 22.04 上安装和使用 GDebi

本文介绍了在Ubuntu 24.04上安装和使用GDebi的方法。GDebi是DPKG的轻量级替代品,能够自动解析并安装.deb包的依赖项。文章详细说明了系统更新、安装GDebi的步骤,并演示了通过GUI和CLI两种方式安装.deb包的操作流程。此外,还提供了验证安装和卸载包的方法。GDebi虽然非必需,但为用户提供了处理依赖项的另一种选择,适合需要安装本地Debian包的用户。

山岚的运维笔记 1991

solidity Dapp ERC20添加即空投合约

ERC20时代一个比较火的话题,空投;空投的方式有很多种。方法一,你在钱包里添加该币种,然后就获取到了空投了;方法二,你向Token合约地址转0个eth,即可获取空投,需要你花点手续费;无论是项目方或者币友们,似乎都比较中意第一种方法,毕竟不用花钱,而且还很方便。今天我们就研究一下这个东西是这么实现的。 首先你需要知道ERC20协议,不知道童鞋们,可以自己到网上去找找看,或者等我...

The future is already here it's just not evenly distributed。 3651

VXLAN技术详解

VXLAN(虚拟可扩展局域网)是一种Overlay二层虚拟化技术,通过MAC-in-UDP封装在IP网络上构建大规模虚拟二层网络。核心组件包括VTEP(隧道端点)、24位VNI(支持1600万个虚拟网络)和VXLAN网关。相比VLAN,VXLAN具有超大规模扩展、跨三层互联、支持虚拟机无缝迁移等优势,适用于云数据中心多租户隔离、跨数据中心互联等场景。其基于IP路由的封装方式无需改造物理网络,为现代云网络提供了弹性、安全的虚拟化解决方案。

kjkdd的博客 595

toolkitten第9周区块链入门:Solidity智能合约完整教程,打造你的第一个以太坊项目

toolkitten 是 #1millionwomentotech 社区开源的学习工具箱,其中的 Summer of Code 第9周区块链课程,是新手学习 Solidity 智能合约的优质起点。这篇完整教程将带你按官方课程节奏,用 4 天时间完成从 Solidity 编译器安装、智能合约编写,到在 Rinkeby 测试网发行自己代币的第一个以太坊项目,零基础也能跟上。 ## 5分钟概念速览:什

gitblog_00996的博客 473

将点云坐标转换成世界坐标的demo

将点云坐标转换成世界坐标的demo

howard789的博客 2206

UG\NX二次开发 分割曲线

分割曲线没有ufun函数?那就换一种思路实现。

王牌飞行员_里海的博客 1147

高效抢领Arbitrum空投:Arb-Claimer攻略

高效抢领Arbitrum空投:Arb-Claimer攻略 在区块链的世界里,空投(Airdrop)常常是新项目启动时的一种营销策略,给社区成员赠送代币以吸引关注和参与。然而,当机会来临时,如何快速、安全地领取这些赠品呢?这就是Arb-Claimer项目的核心价值所在。它是一套基于Solidity智能合约和Ethers.js脚本的开源工具,帮助你在Arbitrum网络上高效地领取空投。 1、项目介绍...

gitblog_00068的博客 809

uni-app - 文本展开 / 收起折叠功能,支持自定义样式(当文本内容超出规定行数后,展开收起折叠的功能)兼容 H5 / App / 小程序且易用更容易修改的插件组件源码,超详细的示例代码及注释

uniapp实现文本的展开与收起功能,uniapp展开全部和收起,uniapp里文本的展开与收起,uniapp中文本内容超出规定行数后展开收起的处理,UNIAPP兼容h5、微信小程序多行文本展开或收起,uni-app中,文字超出隐藏并显示省略号(实现展开、收起全文),uni-app中文本过长-实现折叠与展开效果,中文本内容超出规定行数(字数)后展开收起的处理,超出部分...显示,uniapp适用于uniapp多行文本溢出显示...,多行文本展开或收起,uni-app-文本展开/收起折叠功能,支

🏆 前端领域优质创作者 5642

区块链与智能合约安全实战:从Solidity审计到DeFi漏洞深度剖析

检查项是否完成所有外部调用遵循CEI模式所有关键函数有权限检查使用msg.sender而非tx.origin算术运算已检查溢出(0.8+或SafeMath)外部调用返回值已检查使用SafeERC20包装转账预言机采用TWAP/Chainlink关键状态变更emit事件实现紧急暂停机制升级函数受多签+时间锁保护存储布局在升级时保持兼容部署前完成至少一次独立审计设置漏洞赏金计划。

xlb8888888的博客 962

16. SAP Fiori Elements 应用里图片字段(Image)的显示原理介绍

很多朋友向我反映,学习了 一段时间的 SAP Fiori Elements 开发,但是感觉整套体系对于自己来说还是个黑盒子,很多技术点,看了 SAP 官方帮助文档后,觉得自己懂了,但是一旦需要自己动手做一些东西出来时,又觉得一片茫然。 其实笔者自己也经历过这个过程。究其原因,还是大家对 Fiori Elements 一些技术细节没有理解,对 SAP 官方的知识点仅仅停留在记忆,甚至是死记硬背上面。 不过没有关系,本教程笔者会刻意设置一些练习,让大家动手,在实战中逐渐熟悉 Fiori Elements 这

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 759

C++幂运算全解析:std::pow()函数详解与实战指南

本文详细介绍了C++标准库中的std::pow()函数,包括其基本用法、数学定义和多种重载形式。重点分析了该函数在科学计算、图形处理等领域的实际应用,并提供了性能优化方案如快速幂算法和预计算表。文章还探讨了精度控制、错误处理等关键问题,最后通过一个完整计算器实现展示了综合应用。std::pow()作为基础数学函数,合理使用能显著提升计算效率和代码可靠性。

专注现代C++实战,从核心语法到高性能编程,助力开发者深入掌握系统级编程精髓。 340

Qwen3-32B智能合约审计:Solidity漏洞检测实践

本文介绍了如何在星图GPU平台上自动化部署Clawdbot 整合 qwen3:32b 代理网关与管理平台镜像,高效开展Solidity智能合约漏洞检测。该镜像专为区块链安全审计设计,可快速识别重入、权限缺陷等风险并生成可落地的修复代码,广泛应用于DeFi、GameFi等项目的上线前安全复核。

weixin_31620365的博客 261

Burpsuite 使用教程

Burpsuite 使用教程

xiongIT的博客 8219

Solidity 从 0 到 1 |Web3 开发入门免费共学营

Sonic作为高性能EVM兼容的Layer1区块链(10,000+TPS,1秒确认),推出为期1个月的Solidity开发共学计划,助力开发者从0到1进入Web3世界。课程包含Web3基础、Solidity语言与Sonic生态实战,通过直播答疑+社群互动形式开展,完成者可获认证及周边奖励。

moonshotcommons的博客 729

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

基于多视图学习的NFT合约权限漏洞检测方法与实践

智能合约安全审计是区块链应用开发的关键环节,其核心在于确保合约逻辑的严谨性与权限控制的完备性。传统检测方法如静态分析、符号执行等,往往从单一视角切入,难以全面覆盖跨合约交互、动态权限等复杂场景下的安全隐患。多视图学习作为一种机器学习范式,通过整合多个互补的数据视角,能够构建更鲁棒、更全面的模型。在智能合约安全领域,这一思想具有重要技术价值:通过融合语法结构、控制流、链上交互行为及字节码等多个维度的特征,可以显著提升漏洞检测的准确率与召回率。其应用场景广泛,尤其适用于NFT、DeFi等业务逻辑复杂、权限模型精

benben 348

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

上一篇: Solidity学习之路 - 一个记录邀请关系的通用合约
下一篇: Solidity学习实践-一个遵循ERC721的通用NFT合约
colorful_cloud_sea
博客等级 码龄5年 42粉丝 10原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值