使用 Remix,OpenZeppelin 15 分鐘建立 NFT 智能合約

  • FrankFrank
  • /
  • 14 分鐘閱讀
  • /
  • Mar 27, 2021
  • /
  • - views

NTF 最近是街頭巷尾都在討論。關於 NTF 是什麼和 NTF 到底價值在哪裡這裏不做探討。本文純粹是站在技術角度,教一教大家怎樣用代碼寫一個屬於你自己的 NFT。

NFT 是一種Non-fungible token,是基於 ERC721 或 ERC1155 的智能合約而存在。本文演示的是基於 ERC721 的 NFT。(我另外有一篇文章教大家15分鐘寫 ERC1155 智能合約,裡面會介紹關於 ERC1155 的內容,有興趣也可以去看一看)。

OpenZeppelin

OpenZeppelin 是一個開源的智能合約倉庫,上面已經有許許多多各種各樣的智能合約範本,包括 ERC721 智能合約。因此我們只需要基於 OpenZeppelin 的現有合約,擴展我們自己特定的功能即可。

安裝 OpenZeppelin Contracts

確保已經安裝最新版的 NodeJS,運行下面的指令:

npm install @openzeppelin/contracts

之後在當前目錄下就會安裝好 OpenZeppelin Contracts 的檔案。

使用 Remix IDE

Remix 是 Ethereum 官方提供的 IDE 。包含完整的編譯器、執行合約、發佈合約等等的功能。無須安裝,只要用瀏覽器開啟 https://remix.ethereum.org/ 即可。

Remix 默認情況下會將所有資料存儲在瀏覽器的 Local Storage 中,所以當你清除瀏覽器緩存快取,或者在另外一台電腦打開 Remix,你的資料便會丟失。 Remix 也提供了使用本地文件系統來進行存儲的功能,但需要安裝一個 remixd 本地程式,具體方法可以參考這裡

當你安裝好 remixd 後,便可以透過運行下面的指令來建立 Remix 和本地檔案的連結:

remixd -s <absolute-path-to-the-shared-folder> --remix-ide <your-remix-ide-URL-instance>

撰寫智能合約

完成上面的步驟後,我們便可以開始建立自己的 ERC721 合約了。

// @openzeppelin v3.2.0
pragma solidity ^0.8.0;

import "../node_modules/@openzeppelin/contracts/token/ERC721/presets/ERC721PresetMinterPauserAutoId.sol";

contract FCAT is ERC721PresetMinterPauserAutoId {

    constructor() public
	ERC721PresetMinterPauserAutoId("Frank Cat", "FCAT", "https://www.frank.hk/token/") 	
	{}

	// This allows the minter to update the tokenURI after it's been minted.
	// To disable this, delete this function.
	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);
    }
}

以上的代碼便是利用 OpenZeppelin 的 ERC721 合約建立,我們只是簡單的設置了我們 NFT 的名稱 (Frank Cat),代幣代碼(FCAT)以及代幣 Meta Data URI。

是不是很簡單?

編譯,發佈智能合約

編輯完成後, 就可以切換到 Compile 面板進行編譯。留意要選擇正確的編譯器版本,編譯器版本要和你使用的 OpenZeppelin 合約相同,否則會出現編譯錯誤。

編譯完成後,便可以準備發佈(deploy)了。切換到 Deploy 面板。此時我們要在左上角的 Environment 中選擇【Injected Web 3】,此時便會彈出 MetaMask 進行連結。如果還沒有安裝 MetaMask,可以先在 Chrome Web Store 中安裝。

我們開始嘗試時一般都會選擇在測試網路(testnet)中進行,測試網絡和 Ethereum 主網在技術上沒有區別,但在測試網路中不需要花費真實的 ETH ,而是使用測試網路中的 ETH。一般我們開發的 Blockchain 程式,都要先在測試網路上做全面測試,之後才在主網中上線。要知道 Ethereum 主網的 Gas Fee 可高的驚人。

Ethereum 的測試網路有很多,例如 Ropsten, Rinkeby,Goerli 等等。為了能在 OpenSea 上測試,我們選擇 Rinkeby 測試網路。

使用測試網路,記得要在 MetaMask 中選擇 Rinkeby Test Network。

在 Ethereum 網路上任何導致更改數據的動作都需要花費 ETH,因此發佈智能合約自然需要 ETH。如果沒有 testnet 的 ETH 可以在網上找到很多 testnet faucet 可以免費獲得 testnet 的 ETH ,例如這裡。一切就緒後,就可以按下 【Deploy】,開始發佈你的智能合約,中間會彈出 MetaMask 進行付款確認。

發佈完成後,Remix 會顯示對應的 Transaction Hash,例如我自己上面的例子,對應的 Transaction 可以在 https://rinkeby.etherscan.io 上看到,裡面亦可以看到我們建立的 ERC721 智能合約地址

Mint NFT

合約發佈後,下一步便可以 Mint NFT 啦。

回到 Remix,可以看到 Deployed Contracts 中已經有我們剛才發佈的智能合約,點開他之後可以看到裡面有一個 mint 的 Function,現在我們就可以調用這個 Function 來 Mint NFT 了。在 mint function 後面的 address to 中輸入一個地址,這個地址就會成為新建立的 NFT 的擁有者了。

當 mint 完成後,稍等一段時間便可以在 OpenSea 中看到對應的 NFT 已經誕生了!

到這裡其實我們已經完成了一個最基本的 NFT 的建立。但你可能會問為什麼我們剛才建立的 NFT 沒有圖像呢,要怎麼才能像其他 NFT 一樣有圖像以及其他的一些屬性呢?

原來 NFT 對應的圖像以及其他屬性是由 NFT 的 Metadata 決定,要想 NFT 在 OpenSea 中顯示圖像和其他屬性,還需要指定該 NFT 的 Metadata。

ERC721 Metadata

根據 OpenSea 上的 ERC721 Metadata 標準,OpenSea 會調用我們智能合約中的 tokenURI function,並傳入 tokenID,而這個 function 需要返回一個 HTTP 或 IPFS URL,這個 URL 則必須返回一個 JSON 格式的數據,例如我例子中的這個,而這個 JSON 則定義了我們 NFT 的各種屬性。

用我們上面寫的智能合約為例,留意我們在 constructor 中有如下寫法:

ERC721PresetMinterPauserAutoId("Frank Cat", "FCAT", "https://www.frank.hk/token/") 

其中 https://www.frank.hk/token/ 便是指定了我們 NFT 的 base URI,當調用 tokenURI function 時,我們的合約就會 return https://www.frank.hk/token/<tokenID>

當這個 Metadata 設置好後,再 mint 出的 NFT 就會帶有圖像等屬性了。

當然, 我們建立的 NFT 也是可以在 OpenSea 上交易的哦。

以上就是一個超級簡單的自己寫代碼製作 NFT 的教學了。如果有任何討論,或是錯誤指正,歡迎聯絡我不吝賜教。

感謝閱讀。