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

如何实现智能合约支持ERC20代币替代ETH支付NFT铸造费用

NFT合约新增ERC20支付铸造渠道开发配置指南

合约层改造

  • 引入必要依赖
    直接用OpenZeppelin的标准组件,不用自己重复造轮子:
    import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
    import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
    import "@openzeppelin/contracts/access/Ownable.sol";
    import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
    
    其中SafeERC20用来兼容非标准ERC20代币(比如USDT这类老合约不返回成功布尔值),Ownable做管理权限控制,ReentrancyGuard防重入攻击。
  • 新增状态变量
    using SafeERC20 for IERC20;
    // 支持的支付代币映射:key为ERC20合约地址,value为是否支持
    mapping(address => bool) public supportedPaymentTokens;
    // 各支付代币对应的单NFT铸造价格,单位为对应代币的最小精度
    mapping(address => uint256) public mintPricePerToken;
    // 收款国库地址,所有铸造收入直接打该地址,不留在NFT合约内
    address public treasury;
    
  • 保留原有ETH支付的mint逻辑不动,避免影响已有功能,单独新增ERC20支付的铸造函数:
    function mintWithERC20(address paymentToken, uint256 quantity) external nonReentrant {
        // 基础校验:代币在支持列表、铸造数量不超总上限、数量不为0
        require(supportedPaymentTokens[paymentToken], "Payment token not accepted");
        require(quantity > 0 && totalSupply() + quantity <= MAX_SUPPLY, "Invalid mint quantity");
        // 计算应付总金额
        uint256 totalPayment = mintPricePerToken[paymentToken] * quantity;
        // 直接从用户地址转代币到国库,不经过合约中转
        IERC20(paymentToken).safeTransferFrom(msg.sender, treasury, totalPayment);
        // 复用原有ETH铸造的NFT发放逻辑,给用户转对应数量的NFT
        _mintBatchTo(msg.sender, quantity);
    }
    
  • 新增仅合约所有者可调用的管理函数:
    • 配置支持的支付代币和对应价格:设置时必须核对代币小数精度,比如USDC精度为6,若单NFT价格为10U,对应价格值要填10 * 10**6,填错会直接导致定价错误被薅。
    • 更新国库地址:避免地址私钥丢失后无法接收资金。
    • (可选)新增紧急提现函数:万一有用户误转代币到合约,能由owner提到国库。

测试与上线配置要点

  • 测试阶段优先fork主网环境验证,必须覆盖USDT、USDC、DAI等主流非标准/标准ERC20代币的支付流程,重点测授权、转账、NFT到账全链路,别等上线才发现某类代币转不了。
  • 前端交互要加两个提示:一是ERC20支付需要用户先给NFT合约授权对应消费额度,建议默认授权当次支付的精准金额,不要引导用户无限授权,降低用户资产风险;二是明确标注不同代币的支付价格,避免用户付错。
  • 上线后前20笔铸造手动核对国库地址的资金到账情况,确认代币收款金额、NFT发放数量都对得上,再放开大规模铸造。

高频踩坑提醒

  • 不要图省事把ERC20支付逻辑硬塞进原有的payable mint函数,很容易搞混msg.value判断逻辑,出现免费铸造、多扣钱的问题。
  • 不要用原生的transferFrom方法转ERC20,必须用SafeERC20的safeTransferFrom,不然碰到不返回布尔值的非标准代币会直接交易失败。
  • 不要把铸造收入留在NFT合约里,收款直接打多签控制的国库地址,减少合约被攻击时的资金损失。
  • 不要硬写死各代币的铸造价格,留好owner调整价格的入口,方便根据币价波动、运营需求调整定价。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 23:06:27