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

ERC721合约中确保_mint与_setTokenURI执行完成后写入mapping的方案

ERC721 操作顺序校验实现方案

首先明确:Solidity 为同步顺序执行模型,只要 _mint 和 _setTokenURI 执行过程中没有触发回滚(revert),代码运行到 mapping 写入逻辑时,前面两个操作必然已经完全执行完成,默认不会出现前置操作未完成就执行后续代码的情况。

如果需要增加额外校验增强合约鲁棒性,可以通过 ERC721 内置的查询接口验证两个操作的执行结果,确认成功后再写入 mapping,修改后的代码示例如下:

contract Implement721 is ERC721URIStorage{
uint256 public tokenCounter;
mapping(address => uint[]) public dictBasic;


constructor() ERC721("alvinChris", "ACH")  {
    tokenCounter = 100;
}

function saveData(address _address_sender, string memory _tokenURI)
public returns(address, uint256){
    uint256 newItemId = tokenCounter;
    _mint(_address_sender, newItemId); // 执行mint
    _setTokenURI(newItemId, _tokenURI); // 执行设置URI

    // 新增校验逻辑,确认两个前置操作执行成功
    require(_exists(newItemId), "Mint failed: token does not exist");
    require(
        keccak256(abi.encodePacked(tokenURI(newItemId))) == keccak256(abi.encodePacked(_tokenURI)),
        "Set URI failed: token URI mismatch"
    );
    
    // 校验通过后再写入mapping
    dictBasic[_address_sender].push(newItemId);
    
    tokenCounter = tokenCounter + 1;
    
    return (_address_sender, newItemId);
}
}

校验逻辑说明

  • _exists 是 ERC721 标准内置的视图函数,传入 tokenId 会返回该 token 是否已被成功铸造,可直接验证 _mint 操作结果
  • Solidity 不支持直接对比字符串类型,因此通过 keccak256(abi.encodePacked()) 将两个 URI 转成哈希值后做等值校验,确认 _setTokenURI 已写入正确的 URI
  • 任意一个校验不通过时,require 会直接触发交易回滚,所有状态变更都会被撤销,不会出现部分操作成功的异常中间状态

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 08:45:03