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

如何将我方发行的ERC20代币作为产品支付费用,相关智能合约如何实现?

ERC20代币支付商品售卖智能合约实现答疑

一、适配50枚指定ERC20支付规则的智能合约编写方案

你可以基于OpenZeppelin的标准ERC20接口开发售卖合约,核心逻辑包含授权校验、代币划转、权益发放三个环节,参考实现代码如下:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

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

contract ProductSales is ReentrancyGuard, Ownable {
    // 硬编码指定的ERC20代币合约地址,替换为你方发行的代币实际地址
    address public constant MY_ERC20_TOKEN = 0xYourERC20ContractAddressHere;
    // 单份产品支付金额,假设代币小数位为18,50枚即50 * 10**18
    uint256 public constant PRICE_PER_PRODUCT = 50 * 10 ** 18;

    event ProductPurchased(address indexed buyer, uint256 purchaseTime);

    constructor() Ownable(msg.sender) {}

    // 消费者调用的购买方法
    function purchaseProduct() external nonReentrant {
        // 校验消费者已经给当前合约授权了足够的代币额度
        require(IERC20(MY_ERC20_TOKEN).allowance(msg.sender, address(this)) >= PRICE_PER_PRODUCT, "Insufficient allowance");
        
        // 转移代币到合约所有者(你方收款地址,可自行调整为固定的多签地址等)
        bool transferSuccess = IERC20(MY_ERC20_TOKEN).transferFrom(msg.sender, owner(), PRICE_PER_PRODUCT);
        require(transferSuccess, "Token transfer failed");

        // 这里补充你方产品发放的逻辑,比如mint对应NFT、记录用户权益等
        // _deliverProduct(msg.sender);

        emit ProductPurchased(msg.sender, block.timestamp);
    }

    // 可选:如果需要调整收款地址可以加这个方法,不需要就删掉
    function updateRecipient(address newRecipient) external onlyOwner {
        _transferOwnership(newRecipient);
    }
}

代码说明:

  • 你需要提前把MY_ERC20_TOKEN常量替换为你方实际发行的ERC20代币合约地址,PRICE_PER_PRODUCT要结合你代币的小数位计算,比如你代币小数位是6的话,就写50 * 10 ** 6
  • 消费者调用purchaseProduct方法前,需要先调用你方ERC20代币的approve方法,给当前售卖合约授权至少50枚代币的额度,否则交易会回退
  • 你可以在transferFrom执行成功后,补充你方产品对应的权益发放逻辑,比如发放NFT、记录会员权益等

二、链上逻辑确认支付为指定ERC20代币的方案

核心校验逻辑依赖链上合约地址的唯一性,具体实现方式如下:

  • 在售卖合约中将你方ERC20代币的合约地址设置为不可修改的常量,不要提供任何可以修改该地址的公共方法,也不要在购买接口中允许用户传入代币地址参数
  • 所有和代币相关的交互(额度查询、转账)都只调用上述常量地址对应的合约,不会和其他任何代币地址产生交互,自然就保证了收到的只能是你指定的代币
  • 可选补充校验:部署合约时可以调用该地址的symbol()、decimals()方法,和你预设的代币参数做比对,避免你自己填错代币地址的低级失误。注意不要用symbol/name作为唯一校验依据,恶意仿冒代币可以伪造相同的名称和符号,只有地址是唯一不可伪造的

内容的提问来源于stack exchange,提问作者Gopal Gurram

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 01:06:01