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

ERC721智能合约中每次NFT铸造的审批系统实现可行性问询

ERC721带审批机制的铸造方案

完全可以实现你要的「用户发起请求→所有者审批→完成铸造」流程,同时能优化Gas成本。以下是具体实现思路和代码示例:

核心设计思路

  • 链上存储铸造请求:把用户的铸造请求(地址、NFT元数据、费用状态等)直接存在智能合约里,替代链下数据库的部分功能,确保流程可信。
  • 拆分操作步骤:将「发起请求→审批→铸造」拆分为三个链上函数,既保留审批权限,又减少不必要的Gas支出。
  • 费用托管到合约:用户发起请求时直接把铸造费转到合约,审批完成后再转给所有者,避免链下收费的信任问题。

智能合约实现示例

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

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

contract ApprovedNFT is ERC721, Ownable {
    // 存储铸造请求的结构体
    struct MintRequest {
        address requester;   // 请求用户地址
        string tokenURI;     // NFT元数据地址(如IPFS链接)
        bool isApproved;     // 是否已审批
        bool isMinted;       // 是否已铸造
    }

    uint256 public nextTokenId;
    mapping(uint256 => MintRequest) public mintRequests;
    uint256 public totalRequests;
    uint256 public mintFee; // 铸造费用

    // 事件:方便链下系统跟踪状态
    event MintRequestCreated(uint256 requestId, address requester);
    event MintRequestApproved(uint256 requestId);
    event NFTMinted(uint256 requestId, uint256 tokenId, address to);

    constructor(string memory name, string memory symbol, uint256 _mintFee) 
        ERC721(name, symbol) 
        Ownable(msg.sender) 
    {
        mintFee = _mintFee;
    }

    // 1. 用户发起铸造请求,支付费用到合约
    function requestMint(string calldata _tokenURI) external payable {
        require(msg.value == mintFee, "费用金额不符");
        totalRequests++;
        mintRequests[totalRequests] = MintRequest({
            requester: msg.sender,
            tokenURI: _tokenURI,
            isApproved: false,
            isMinted: false
        });
        emit MintRequestCreated(totalRequests, msg.sender);
    }

    // 2. 所有者审批特定请求
    function approveMint(uint256 _requestId) external onlyOwner {
        MintRequest storage req = mintRequests[_requestId];
        require(!req.isMinted, "该请求已完成铸造");
        req.isApproved = true;
        emit MintRequestApproved(_requestId);
    }

    // 3. 用户领取已审批的NFT(用户支付Gas)
    function claimNFT(uint256 _requestId) external {
        MintRequest storage req = mintRequests[_requestId];
        require(req.requester == msg.sender, "非请求发起者");
        require(req.isApproved, "请求未通过审批");
        require(!req.isMinted, "该请求已完成铸造");

        req.isMinted = true;
        _safeMint(msg.sender, nextTokenId);
        emit NFTMinted(_requestId, nextTokenId, msg.sender);
        // 将合约中的费用转给所有者
        payable(owner()).transfer(mintFee);
        nextTokenId++;
    }

    // 可选:所有者批量铸造已审批请求(所有者支付Gas,适合批量处理)
    function batchMintApproved(uint256[] calldata _requestIds) external onlyOwner {
        uint256 feeToTransfer = mintFee * _requestIds.length;
        require(address(this).balance >= feeToTransfer, "合约余额不足");

        for(uint256 i = 0; i < _requestIds.length; i++){
            uint256 reqId = _requestIds[i];
            MintRequest storage req = mintRequests[reqId];
            require(req.isApproved && !req.isMinted, "请求不符合铸造条件");
            
            req.isMinted = true;
            _safeMint(req.requester, nextTokenId);
            emit NFTMinted(reqId, nextTokenId, req.requester);
            nextTokenId++;
        }
        payable(owner()).transfer(feeToTransfer);
    }

    // 所有者提取合约余额(防止费用卡住)
    function withdrawBalance() external onlyOwner {
        payable(owner()).transfer(address(this).balance);
    }

    // 所有者修改铸造费用(可选)
    function setMintFee(uint256 _newFee) external onlyOwner {
        mintFee = _newFee;
    }
}

业务流程说明

  1. 用户发起请求:用户调用requestMint,支付铸造费并提交NFT的元数据链接(如IPFS地址),生成唯一请求ID,仅需支付一次Gas。
  2. 所有者审批:你可以通过链下系统监听MintRequestCreated事件,获取所有待审批请求;确认信息无误后,调用approveMint标记请求为已审批,若批量审批可大幅降低Gas成本。
  3. 完成铸造:
    • 方式一:用户收到审批通知后,调用claimNFT领取NFT,同时合约自动将费用转给你。
    • 方式二:你调用batchMintApproved批量处理所有已审批请求,一次Gas完成多份NFT铸造,用户无需额外操作。

优化点说明

  • 相比你之前的方案,新流程最多只需要两次Gas(用户发起+用户领取/所有者批量铸造),且批量操作能进一步降低Gas成本。
  • 所有状态都在链上存储,避免链下数据库和链上状态不一致的问题。
  • 可通过添加事件,轻松对接你的现有数据库,实现请求状态的实时同步。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 05:40:22