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
相关产品推荐
相关产品推荐

