You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Solidity合约中存储授权地址仅允许指定地址提现?

完全可以实现,这是以太坊空投类合约的标准需求,具体实现方案如下:

核心实现逻辑
  • 你需要三个核心合约存储变量:合约所有者地址owner、白名单额度映射mapping(address => uint256) public claimableAmount(存储每个符合规则用户可提取的代币数量)、活动结束时间戳uint256 public airdropEndTime(控制提现开启时间)
  • 用onlyOwner权限修饰符限制仅你可以添加、修改白名单用户的可提现额度,避免无关人员篡改空投规则
  • 提现逻辑天然由用户发起,交易手续费自动由调用接口的用户承担,不需要你额外支付;仅当用户在白名单内有可提取额度、且活动已结束时,才可成功提现,提现后自动清空对应地址的可提额度,避免重复提现
参考代码片段
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

contract AirdropClaim is Ownable {
    // 要发放的空投代币合约地址
    IERC20 public immutable rewardToken;
    // 空投活动结束的秒级时间戳
    uint256 public immutable airdropEndTime;
    // 存储每个用户可领取的空投数量
    mapping(address => uint256) public claimableAmount;

    event Claimed(address indexed user, uint256 amount);

    // 构造函数初始化:传入代币地址、活动持续时长(1个月可填30*86400)
    constructor(address _rewardToken, uint256 _duration) {
        rewardToken = IERC20(_rewardToken);
        airdropEndTime = block.timestamp + _duration;
    }

    // 仅所有者可批量设置符合规则的用户可领额度,活动期间可随时修改
    function setAirdropWhitelist(address[] calldata users, uint256[] calldata amounts) external onlyOwner {
        require(users.length == amounts.length, "参数长度不匹配");
        require(block.timestamp < airdropEndTime, "空投活动已结束,不可修改白名单");
        for (uint256 i = 0; i < users.length; i++) {
            claimableAmount[users[i]] = amounts[i];
        }
    }

    // 用户提现接口,由用户自主调用,GAS费用户自行承担
    function claim() external {
        require(block.timestamp >= airdropEndTime, "空投活动未结束,暂不可提现");
        uint256 amount = claimableAmount[msg.sender];
        require(amount > 0, "你没有可提取的空投额度");
        // 先清零额度避免重入攻击
        claimableAmount[msg.sender] = 0;
        rewardToken.transfer(msg.sender, amount);
        emit Claimed(msg.sender, amount);
    }

    // 可选功能:活动结束后所有者可提取未被领取的剩余代币
    function withdrawRemaining() external onlyOwner {
        require(block.timestamp >= airdropEndTime, "空投活动未结束,不可提取剩余代币");
        uint256 balance = rewardToken.balanceOf(address(this));
        rewardToken.transfer(owner(), balance);
    }
}
注意事项
  • 部署合约时请准确计算活动时长,部署后活动结束时间不可修改,避免后续规则纠纷
  • 合约部署完成后,你需要提前将全部要发放的空投代币转入该合约地址,否则用户提现时会因为合约余额不足失败
  • 活动结束后白名单修改接口会自动禁用,无法再调整用户可提现额度
  • 代码默认已实现单地址仅可提现一次的逻辑,不会出现重复冒领的问题

内容的提问来源于stack exchange,提问作者Danilo Escobar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 06:36:04