- A+
所属分类:NFT
一、说明
在铸造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+视频(BSC币安链+TRX波场链)NFT发行教程及合约源代码下载地址:
添加VX或者telegram获取全程线上免费指导
本文是全系列中第6 / 17篇:NFT发行
- 币安链BSC上NFT发行教程——BSC链铸造nft并转账(空投)到其他钱包地址【pdf+视频BSC链NFT发行教程下载】
- 币安链BSC上NFT发行教程——NFT元数据模板,支持上线opensea并交易【pdf+视频BSC链NFT发行教程下载】
- 波场链TRX上NFT发行教程——web页面上传NFT头像到IPFS链【pdf+视频TRX链NFT发行教程下载】
- 币安链BSC上NFT发行教程——两种方式在BSC币安链上铸造NFT及部署NFT合约【pdf+视频BSC链NFT发行教程下载】
- 币安链BSC上NFT发行教程——NFT单品铸造完成后无法在tp钱包显示图片故障处理及解决方法【pdf+视频BSC链NFT发行教程下载】
- 币安链BSC上NFT发行教程——自动创建tokenid的NFT合约源码实现【pdf+视频BSC链NFT发行教程下载】
- 比特币NFTs: Ordinals NFT 图片怎么从rawTransaction原始交易中解析
- NFTScan | 06.12~06.18 NFT 市场热点汇总
- Safe 多签钱包签名消息, 支持签名登录 Opensea
- 币安BSC智能链发币教程——扫描所有NFT,根据NFT持有情况分红代币【pdf+视频BSC发币教程下载】
- 币安链BSC上NFT发行教程——NFT根据拍卖次数指数型递增增加价格【pdf+视频BSC链NFT发行教程下载】
- 币安链BSC上NFT发行教程——NFT合约中的代理人针对所有NFT的授权功能【pdf+视频BSC链NFT发行教程下载】
- 如何使用 Circom 和 SnarkJS 实现极简 NFT zkRollup
- 币安BSC智能链NFT Market搭建教程——搭建基于BSC链的NFT Market合约实现【pdf+视频BSC NFT教程下载】
- 波场链TRX上NFT发行教程——NFT中元数据合约源代码实现【pdf+视频TRX链NFT发行教程下载】
- 波场链TRX上NFT发行教程——部署波场链上的NFT合约【pdf+视频TRX链NFT发行教程下载】
- 波场链TRX上NFT发行教程——使用腾讯云存储代替ipfs存储的实现方式【pdf+视频TRX链NFT发行教程下载】
- 我的微信
- 这是我的微信扫一扫
- 我的电报
- 这是我的电报扫一扫