一、说明
在铸造NFT单品的合约中,大部分合约需要手动指定tokenid,如果在铸造NFT单品时,错误的指定了tokenid,就会造成tokenid不连续的情况。虽然该问题不会导致技术上的故障,但是会导致NFT单品的tokenid不连续,给人感觉是部分NFT单品出现了异常。
基于该问题,优化调整NFT合约代码,NFT单品的tokenid由合约来自动递增产出,代替由铸造这miner手动输入,以解决tokenid不连续的问题。
二、合约代码实现
tokenid递增产生的NFT合约代码实现:
1、业务合约接口类IWZDAONFT
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; interface IWZDAONFT{ function mint(address _owner) external returns(uint256 tokenId); function getSurplusSupply() external view returns(uint256); }
2、访问权限控制合约接口
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import "@openzeppelin/contracts/access/Ownable.sol"; abstract contract AccessControl is Ownable{ mapping(address => bool) private _operators; event SetOperator(address indexed add, bool value); function setOperator(address _operator, bool _v) external onlyOwner { _operators[_operator] = _v; emit SetOperator(_operator, _v); } function isOperator(address _address) external view returns(bool){ return _operators[_address]; } modifier onlyOperator() { require(_operators[msg.sender]); _; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
4、tokenid递增计数控制器合约类
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Counters.sol) pragma solidity ^0.8.0; /** * @title Counters * @author Matt Condon (@shrugs) * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number * of elements in a mapping, issuing ERC721 ids, or counting request ids. * * Include with `using Counters for Counters.Counter;` */ library Counters { struct Counter { // This variable should never be directly accessed by users of the library: interactions must be restricted to // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add // this feature: see https://github.com/ethereum/solidity/issues/4637 uint256 _value; // default: 0 } function current(Counter storage counter) internal view returns (uint256) { return counter._value; } function increment(Counter storage counter) internal { unchecked { counter._value += 1; } } function decrement(Counter storage counter) internal { uint256 value = counter._value; require(value > 0, "Counter: decrement overflow"); unchecked { counter._value = value - 1; } } function reset(Counter storage counter) internal { counter._value = 0; } }
5、业务主合约实现类
//SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol"; import "@openzeppelin/contracts/utils/Counters.sol"; import "./access/AccessControl.sol"; import "./interfaces/IWZDAONFT.sol"; contract NFT is ERC721,IWZDAONFT,ERC721Enumerable,ERC721Burnable,AccessControl { string public baseURI; uint256 public constant MAX_SUPPLY = 108; using Counters for Counters.Counter; Counters.Counter private _tokenIds; constructor( string memory name_,string memory symbol_) ERC721(name_, symbol_){ } function supportsInterface(bytes4 interfaceId) public view override(ERC721, ERC721Enumerable) returns (bool) { return super.supportsInterface(interfaceId); } function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal override(ERC721, ERC721Enumerable) { super._beforeTokenTransfer(from, to, tokenId); } function getSurplusSupply() public view returns(uint256){ return MAX_SUPPLY - totalSupply(); } function mint(address _owner) external onlyOperator returns(uint256 tokenId) { require(getSurplusSupply() > 0 ,"Exceeded maximum supply"); tokenId=_tokenIds.current(); _safeMint(_owner,tokenId); _tokenIds.increment(); } function setBaseURI(string memory _uri) external onlyOwner { baseURI = _uri; } function _baseURI() internal view override returns (string memory) { return baseURI; } }
6、开源后的合约详情如下
参考合约地址:
此内容仅供注册用户可见,请登录!
至此,完成自动创建tokenid的NFT合约源码实现所有操作流程。
pdf+视频(BSC币安链+TRX波场链)NFT发行教程及合约源代码下载:
币安智能链BSC+波场链TRX NFT发行(合约部署、开源、参数配置、开发、故障处理、工具使用)教程下载:
币安智能链BSC+波场链TRX NFT发行合约源代码下载
pdf+视频(TRX波场链+BSC币安链)NFT发行教程及合约源代码下载地址:
此内容仅供注册用户可见,请登录!
添加VX或者telegram获取全程线上免费指导
评论前必须登录!
注册