跳至內容
0%

如何建立 NFT

作者:Alchemy Team

最後更新:2021年10月7日3 分鐘閱讀

本教學將帶你使用 Ethereum 和 Inter Planetary File System(IPFS)撰寫並部署一個非同質化(ERC721)代幣智慧合約。

預估完成時間:約 15 分鐘

即使你完全不關心這個領域,應該也已經注意到各大新聞媒體都在報導 NFT 的興起。

隨著 NFT 讓區塊鏈進入大眾視野,現在正是自己動手發布 NFT(ERC-721 代幣)到 Ethereum 區塊鏈上、親身理解這股熱潮的好機會!

在本教學中,我們會使用 Metamask、Solidity、Hardhat、Pinata 和 Alchemy,在 Sepolia 測試網路上建立並部署一個 ERC-721 智慧合約(如果你現在還不了解這些名詞的意思也沒關係,我們會解釋)。在本教學的第二部分,我們會說明如何用智慧合約鑄造一個 NFT,第三部分則會說明如何在 Metamask 上查看你的 NFT。

當然,如果你在任何階段有疑問,歡迎造訪 Alchemy 支援中心!

步驟 1:連接到 Ethereum 網路

向 Ethereum 區塊鏈發送請求的方法有很多種,但為了簡化流程,我們會使用 Alchemy 的免費帳號——這是一個區塊鏈開發者平台兼 API,讓我們不需要自行運行節點就能與 Ethereum 鏈通訊。

在本教學中,我們也會運用 Alchemy 的開發者工具進行監控與分析,了解智慧合約部署背後實際發生的事情。如果你還沒有 Alchemy 帳號,可以在這裡免費註冊。

步驟 2:建立你的 App(以及 API key)

建立 Alchemy 帳號後,你可以透過建立一個 App 來產生 API key。這樣我們就能向 Sepolia 測試網路發送請求。如果你想更了解測試網路,可以參考這篇指南。

  1. 將滑鼠移到導覽列的「Apps」上,點選「Create App」,進入 Alchemy Dashboard 的「Create App」頁面
Alchemy 儀表板:從 Apps 選單建立新的 app
建立新的 app
  1. 為你的 App 命名(我們取名為「My First NFT!」),填寫簡短說明,Environment 選擇「Staging」(用於你的 App 記錄管理),Network 選擇「Sepolia」。
舊版 Alchemy 儀表板的 app 建立畫面,含測試網路選擇器
為你的 app 命名並輸入描述
  1. 點選「Create app」就完成了!你的 App 應該會出現在下方的表格中。

步驟 3:建立一個 Ethereum 帳號(地址)

我們需要一個 Ethereum 帳號來發送與接收交易。在本教學中,我們會使用 Metamask——一個瀏覽器中的虛擬錢包,用來管理你的 Ethereum 帳號地址。如果你想更了解 Ethereum 上的交易如何運作,可以查看 Ethereum 基金會的這個頁面。

你可以在這裡免費下載並建立一個 Metamask 帳號。在建立帳號時,或如果你已經有帳號,請務必切換到 Sepolia 測試網路(這樣我們就不會動用到真的錢)。

舊版 MetaMask 錢包設定畫面,含測試網路選擇器
下載並建立 Metamask 帳號

步驟 4:從水龍頭取得 ether

為了將智慧合約部署到測試網路,我們需要一些假的 Eth。要取得 Eth,你可以前往 Sepolia faucet,輸入你的 Sepolia 帳號地址,並請求 Sepolia Eth。不久之後,你應該就能在 Metamask 帳號中看到 Eth!

步驟 5:檢查你的餘額

為了雙重確認餘額確實入帳,讓我們使用 Alchemy 的 composer 工具發送一個 eth_getBalance 請求。這會回傳我們錢包中的 Eth 數量。輸入你的 Metamask 帳號地址並點選「Send Request」後,你應該會看到類似這樣的回應:

{"jsonrpc": "2.0", "id": 0, "result": "0xde0b6b3a7640000"}

注意: 這個結果單位是 wei,不是 eth。wei 是 ether 最小的計價單位。wei 換算成 eth 的公式是:1 eth = 10¹⁸ wei。所以如果我們把 0xde0b6b3a7640000 轉換成十進位,會得到 1*10¹⁸,也就是 1 eth。

太好了!我們的假錢都到位了!🤑

步驟 6:初始化我們的專案

首先,我們需要為專案建立一個資料夾。打開你的命令列並輸入:

進入專案資料夾後,我們會用 npm init 來初始化專案。如果你還沒安裝 npm,請依照這些說明安裝(我們也會需要 Node.js,所以也一併下載吧!)。

安裝過程中的問題怎麼回答其實都無所謂,以下是我們的回答方式供你參考:

確認 package.json 後,就完成了!

步驟 7:下載 Hardhat

Hardhat 是一個用來編譯、部署、測試和除錯你的 Ethereum 軟體的開發環境。它能幫助開發者在正式上鏈之前,先在本機建置智慧合約與應用程式。

打開終端機,確認你在 my-nft 專案資料夾內,然後執行:

想了解更多安裝細節,可以查看這個頁面。

步驟 8:建立 Hardhat 專案

在我們的專案資料夾內執行:

接著你會看到歡迎訊息,並被要求選擇要做的事。選擇「create an empty hardhat.config.js」:

這會為我們產生一個 hardhat.config.js 檔案,這裡就是我們用來設定整個專案的地方(在步驟 13 會用到)。

步驟 9:新增專案資料夾

為了讓專案結構清楚,我們會建立兩個新資料夾。在命令列中導覽到專案的根目錄,然後輸入:

contracts/ 用來存放我們的 NFT 智慧合約程式碼

scripts/ 用來存放部署與操作智慧合約的腳本

步驟 10:撰寫我們的合約

環境設定好了,接下來要進入更有趣的部分:撰寫智慧合約程式碼!

用你喜歡的編輯器(我們喜歡用 VSCode)打開 my-nft 專案。智慧合約是用一種叫做 Solidity 的語言撰寫,我們也會用它來撰寫 MyNFT.sol 智慧合約。

  1. 到「contracts」資料夾,建立一個新檔案叫 MyNFT.sol

  2. 以下是我們的 NFT 智慧合約程式碼,基於 OpenZeppelin 函式庫的 ERC721 實作。將以下內容複製貼上到你的 MyNFT.sol 檔案中。

注意:如果你想透過智慧合約為 NFT 訂定價格,可以參考這篇教學。

  1. 因為我們繼承了 OpenZepplin 合約函式庫的類別,請在命令列執行以下指令,將該函式庫安裝到我們的資料夾中:

textnpm install @openzeppelin/contracts@3.1.0-solc-0.7

那麼,這段程式碼到底做了什麼?我們逐行來分析。

在第 5-7 行,我們的程式碼繼承了三個 OpenZepplin 智慧合約類別:

  • @openzeppelin/contracts/token/ERC721/ERC721.sol 包含 ERC721 標準的實作,我們的 NFT 智慧合約會繼承這個實作。(要成為有效的 NFT,你的智慧合約必須實作 ERC721 標準的所有方法。)想了解更多繼承來的 ERC721 函式,可以查看這裡的介面定義。

  • @openzeppelin/contracts/utils/Counters.sol 提供只能以 1 為單位遞增或遞減的計數器。我們的智慧合約使用計數器來追蹤已鑄造的 NFT 總數,並將唯一 ID 設定給我們的新 NFT。每個用智慧合約鑄造的 NFT 都必須被分配一個唯一的 ID——這裡的唯一 ID 就是由目前已存在的 NFT 總數決定。舉例來說,我們用智慧合約鑄造的第一個 NFT ID 為「1」,第二個 NFT ID 為「2」,依此類推。

  • @openzeppelin/contracts/access/Ownable.sol 為我們的智慧合約設定存取控制,讓只有智慧合約的擁有者(也就是你)能夠鑄造 NFT。請注意,是否加入存取控制純粹是個人偏好。如果你希望任何人都能用你的智慧合約鑄造 NFT,可以移除第 10 行的 Ownable 以及第 17 行的 onlyOwner。

在第 10-28 行,是我們自訂的 NFT 智慧合約,內容出乎意料地短——只包含一個計數器、一個建構子,以及單一一個函式!這都要歸功於我們繼承的 OpenZepplin 合約,它們已經實作了建立 NFT 所需的大部分方法,例如 ownerOf(回傳 NFT 的擁有者)和 transferFrom(轉移 NFT 的所有權)。

在第 14 行,你會注意到我們將兩個字串「MyNFT」和「NFT」傳入 ERC721 的建構子。第一個變數是智慧合約的名稱,第二個是它的符號。這兩個變數你都可以自由命名!

最後,從第 16 行開始,是我們的函式 mintNFT(),它讓我們能夠鑄造一個 NFT!你會注意到這個函式接收兩個變數:

  • address recipient 指定將收到你剛鑄造的 NFT 的地址

  • string memory tokenURI 是一個字串,應該指向一份描述 NFT 中繼資料(metadata)的 JSON 文件。NFT 的中繼資料才是真正賦予它生命力的部分,讓它能擁有額外的屬性,例如名稱、描述、圖片和其他特性。在本教學的第二部分,我們會說明如何設定這個中繼資料。

mintNFT 呼叫了一些繼承自 ERC721 函式庫的方法,最終回傳一個代表剛鑄造 NFT ID 的數字。

步驟 11:將 MetaMask 和 Alchemy 連接到你的專案

現在我們已經建立了 Metamask 錢包、Alchemy 帳號,也寫好了智慧合約,是時候把這三者連接起來了。

從你的虛擬錢包發出的每一筆交易,都需要用你獨一無二的私鑰進行簽名。為了讓我們的程式取得這個授權,我們可以將私鑰(以及 Alchemy API key)安全地存放在一個環境變數檔案中。

想了解更多發送交易的細節,可以查看這篇教學,內容是關於用 web3 發送交易。

首先,在你的專案目錄中安裝 dotenv 套件:

接著,在專案的根目錄建立一個 .env 檔案,並在裡面加入你的 Metamask 私鑰和 HTTP Alchemy API URL。

注意:你的 .env 檔案名稱必須是 .env!請不要改成 xx.env 之類的名稱

  • 依照這些說明匯出你在 Metamask 的私鑰

  • 請參考下方取得 HTTP Alchemy API URL 並複製到剪貼簿

Alchemy 儀表板:複製 app 的 HTTP API URL 供 .env 檔案使用
複製你的 Alchemy API key

你的 .env 應該會像這樣:

步驟 12:安裝 Ethers.js

Ethers.js 是一個函式庫,它將標準的 JSON-RPC 方法包裝成更易用的方法,讓我們更容易與 Ethereum 互動並發送請求。

Hardhat 讓整合外掛以取得額外工具與延伸功能變得非常簡單。我們會使用 Ethers 外掛來部署合約(Ethers.js 有一些非常簡潔的合約部署方法)。

在你的專案目錄中輸入:

在下一步中,我們也會在 hardhat.config.js 裡引入 ethers。

步驟 13:更新 hardhat.config.js

到目前為止我們已經新增了幾個相依套件和外掛,現在需要更新 hardhat.config.js,讓我們的專案知道這些設定。

將你的 hardhat.config.js 更新成這樣:

步驟 14:編譯我們的合約

為了確認到目前為止一切正常,讓我們編譯合約。compile 是 hardhat 內建任務之一。

在命令列執行:

你可能會看到一則關於原始檔案未提供 SPDX license identifier 的警告,但不用擔心——希望其他部分都沒問題!如果有問題,你可以從 Alchemy Dashboard 開啟支援單。

步驟 15:撰寫部署腳本

現在合約已經寫好,設定檔也準備妥當,接下來要撰寫合約部署腳本。

到 scripts/ 資料夾,建立一個新檔案叫 deploy.js,加入以下內容:

Hardhat 在他們的合約教學中對每一行程式碼的作用都有非常好的說明,我們在這裡沿用了他們的解釋。

ethers.js 中的 ContractFactory 是用來部署新智慧合約的抽象概念,因此這裡的 MyNFT 就是我們 NFT 合約實例的工廠(factory)。使用 hardhat-ethers 外掛時,ContractFactory 和 Contract 實例預設會連接到第一個 signer。

在 ContractFactory 上呼叫 deploy() 會開始部署,並回傳一個會解析為 Contract 的 Promise。這個物件包含對應我們智慧合約每個函式的方法。

步驟 16:部署我們的合約

我們終於準備好部署智慧合約了!回到專案目錄的根目錄,在命令列執行:

接著你應該會看到類似這樣的內容:

如果我們前往 Sepolia Etherscan 搜尋我們的合約地址,應該能看到它已經成功部署。這筆交易看起來會像這樣:

Etherscan 交易畫面,確認 NFT 智慧合約已成功部署
地址部署成功

From 地址應該會與你的 Metamask 帳號地址相符,而 To 地址則會顯示「Contract Creation」。如果點進這筆交易,我們會在 To 欄位看到我們的合約地址:

太棒了!你剛把 NFT 智慧合約部署到 Ethereum 鏈上 🎉
太棒了!你剛把 NFT 智慧合約部署到 Ethereum 鏈上 🎉

想了解背後實際發生的事情,讓我們前往 Alchemy dashboard 的 Explorer 分頁。如果你有多個 Alchemy App,記得依 App 篩選,選擇「MyNFT」。

Alchemy 儀表板的 Explorer 分頁,列出合約部署期間發出的 JSON-RPC 呼叫
前往 Alchemy 儀表板的 Explorer 分頁

在這裡你會看到一系列 JSON-RPC 呼叫,這些都是我們呼叫 .deploy() 函式時,Hardhat/Ethers 在背後為我們發出的請求。

這裡有兩個值得特別說明的呼叫:eth_sendRawTransaction,這是實際將我們的智慧合約寫入 Sepolia 鏈上的請求;以及 eth_getTransactionByHash,這是根據交易雜湊值讀取交易資訊的請求(發送交易時的一種常見模式)。

想了解更多發送交易的細節,可以查看這篇關於用 Web3 發送交易的教學。

本教學第一部分到此結束。在第二部分,我們會實際透過鑄造 NFT 來操作我們的智慧合約,第三部分則會說明如何在 Metamask 中查看你的 NFT!🤑

Alchemy 電子報

搶先掌握最新發布消息

訂閱我們的電子報

取得 Alchemy 最新產品更新與資源

A
O
D
+
超過 80,000 名訂閱者

輸入您的電子郵件地址,即表示您同意接收我們的行銷通訊與產品更新。您了解 Alchemy 會依照我們的隱私權聲明處理所收到的資訊。您可以隨時取消訂閱。