大家也可以做個小範例

NFT SmartContract To Opensource

以下用OpenZeppelin 實作,當然實作方式很多以下係使用

ERC721URIStorage、ERC721PresetMinterPauserAutoId

設定新的NFT(也是簡單搞定...)

ERC721URIStorage

// contracts/GameItem.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "<https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.5.0/contracts/token/ERC721/extensions/ERC721URIStorage.sol>";
import "<https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.5.0/contracts/utils/Counters.sol>";

contract GameItem is ERC721URIStorage {
    using Counters for Counters.Counter; // utils 提供的Lab可使用(計數)
    Counters.Counter private _tokenIds;

    constructor() ERC721("GameItem", "ITM") {}

    function awardItem(address player, string memory tokenURI)
        public
        returns (uint256)
    {
        _tokenIds.increment();// 增號

        uint256 newItemId = _tokenIds.current(); //現在的代號
        _mint(player, newItemId);
        _setTokenURI(newItemId, tokenURI);

        return newItemId;
    }
}

上面有引用

  1. using Counters for Counters.Counter 這是引用OpenZeppelin的 utils

  2. ERC721URIStorage 就是設定NFT 路徑_setTokenURI的實作。

ERC721PresetMinterPauserAutoId

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "<https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.5.0/contracts/token/ERC721/presets/ERC721PresetMinterPauserAutoId.sol>";

contract OpenzeppelinPresetMinterPauserAutoId is ERC721PresetMinterPauserAutoId {

    constructor() ERC721PresetMinterPauserAutoId("TEST NFT","TNF","<https://test>"){}

    function setTokenURI(uint256 tokenId, string memory tokenURI) public {
        require(hasRole(MINTER_ROLE, _msgSender()), "web3 CLI: must have minter role to update tokenURI");
        setTokenURI(tokenId, tokenURI);
    }
}

如果我們使用 ERC721PresetMinterPauserAutoId 建立NFT,自動提供如下角色及特色

身份:

MINTER_ROLE 鑄造者角色

PAUSER_ROLE 暫停角色