# 連小學生都能懂的智能合約開發-開始來寫你的第一個NFT(1) # 系列前言 在這系列教學文會盡量忽略底層原理,只著重介紹開發上會遇到的專有名詞 這系列發出第一個NFT為目標,NFT是一個發布在區塊鏈上無法被更改,且獨一無二的token,本篇會以開發為主,不會對NFT的特性跟應用做過多解釋 過程會採用 **Solidity** 撰寫,沒有學過沒有關係,這個系列會手把手教你,過程不需要裝任何東西,我們會在線上 IDE **Remix** 做開發 由於在教學部分我希望可以盡量詳細一點,整個內容會稍顯冗長,所以還請讀者自行根據程度以及速度去做調配跟篩選 一開始我會先以成功執行為目標,一些細節我會在簡單提點,並在之後的篇章做講解,或提供關鍵字跟參考連結,因此若有看不懂或不理解的地方,可以先行略過,待之後做更深入的研究 # 前置準備 - 需要你有寫過任何一個程式,對基本的程式概念跟資料型態有概念 - 對物件導向(OOP)有些微了解 - 有聽過加密貨幣,如果了解區塊鏈的運作部分原理更好 # 開始開發 在開始之前我們要先知道合約一定需先經過部署,以其他語言來說需要先做編譯再執行,而智能合約的順序則為 #### 撰寫->編譯->部署->執行 由上述可以看到在執行跟編譯中間還多了個部署,這也是合約跟其他程式稍微不太一樣的地方 ## 部署合約 1. 首先進入 [Remix](https://remix.ethereum.org/#optimize=false&runs=200&evmVersion=null&version=soljson-v0.8.7+commit.e28d00a7.js&lang=en) 2. 進入畫面後點選左上角 "+" ![](https://i.imgur.com/2KFMwr4.png) 3. Template 選擇 ERC721,並且 Features 勾選 Mintable ,至於底下的 Workspace name 是你這個專案的名稱,打喜歡的就可以,我這邊用預設,好了之後按下OK ![](https://i.imgur.com/SHX3x6o.png) 4. 接下來進到畫面之後,點開contracts之後,查看MyToken.sol當中的程式碼 ![](https://i.imgur.com/a0YARy3.png) 預設的程式碼如下 ```solidity= // SPDX-License-Identifier: MIT pragma solidity ^0.8.9; import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; contract MyToken is ERC721, Ownable { constructor() ERC721("MyToken", "MTK") {} function safeMint(address to, uint256 tokenId) public onlyOwner { _safeMint(to, tokenId); } } ``` 這邊我們稍微來解釋MyToken合約的內容,當中使用solidity語言撰寫,我會在本系列的第二篇再針對solidity做更深入的講解 Line 1 -> 宣告這個合約要套用哪種Lincense,這邊用的是MIT Line 2 -> 選擇 Solidity 編譯器的版本 Line 4 5 -> 這邊我們 import ERC721 跟 Ownable 這兩個合約進來,供 MyToken 繼承用 Line 7 -> 我們創建了一個 MyToken 的 contract,並且繼承了 ERC721 跟 Ownable 兩個 contract Line 8 -> 建構式,一開始部署 MyToken 的時候會執行建構式的當中的程式,但是可以看到 {} 內沒有任何程式,意思是我們讓 MyToken 部署時不需要做任何事情 > 雖然 MyToken 本身沒有任何建構式,但是 ERC721 這個 contract 是有自己的建構式的,所以在constructor 旁邊需要寫 `ERC721("MyToken", "MTK")`,這邊若有點不太理解沒關係,之後會做更詳細的解說 Line 10 -> 我們定義了一個`safeMint(address to, uint256 tokenId)`這個 function,並且設定為 public,熟知 OOP 的朋友應該對這個不陌生,意即允許內部跟外部的調用,然後`safeMint`裡面執行`_safeMint(to, tokneId)`這個從 ERC721 繼承而來的 function 至於參數部分,`to`的資料型別是 `address`,這是 Solidity 特有的資料型別,屬於公私鑰加密當中的公鑰部分,是由 20 個 bytes 所組成,同時也是 Ethereum 用來表示帳戶的方法(這後面會有更詳盡的解釋,這邊可以先理解為每個人在 Ethereum 都會自動生成一個 address 當作自己的帳戶即可),而 `tokenId` 是 `uint256`,代表無號整數且範圍是 **0~2^256-1** 而整個`safeMint`做的事情是鑄造一個Token ID(每個NFT都會有自己的ID且不會重複,這也是非同質性所在)為`tokenId`的NFT給`to`這個address > 後面的onlyOwner是屬於solidity的用法,是Ownable這個contract裡面的東西,可以先理解為讓`safeMint(address to, uint256 tokenId)`只允許合約部署者去調用,其餘人都不可以 5. 可以點左側紅框處,可以選上面的Compiler Version(這邊記得選0.8.9以上),底下藍色的按鈕可以Compile,正常來說這邊不會出現任何錯誤,看到左側出現一個綠色勾勾就是編譯成功 ![](https://i.imgur.com/RBlqs5d.png) 6. 點選左側紅框圈選處,這邊是執行function跟部署合約的欄位,在Deploy按鈕上方選單我們可以選擇要部署的合約,接著點選Deploy來進行部署 ![](https://i.imgur.com/UE0eSiZ.png) 7. 部署成功之後可以看到部署成功的訊息,以及在左下方已部署的欄位部分多,多了一個合約,也就是我們剛剛部署的MyToken合約 ![](https://i.imgur.com/uJsFKw5.png) ## Mint NFT 在上一個階段,我們成功部署了合約 現在,可以執行已部署合約當中所擁有的function 而我們這邊要做的動作就是Mint一個NFT出來 1. 將左下角的MyToken展開,可以看到這邊有很多的function可供調用,大部分都是繼承至ERC721跟Ownable的 ![](https://i.imgur.com/KnhrpXo.png) 2. 我們這邊要執行的function只有一個,也就是MyToken自己的`safeMint`,這邊再將`safeMint`進一步展開,可以看到有兩個欄位可供輸入,分別對應參數`to`跟`tokenId` ![](https://i.imgur.com/ZT12HN8.png) 3. 接著我們要輸入參數並執行,`tokenId`的部分比較簡單,直接輸入一個數字`1`即可,至於`to`因為是`address`,由20bytes組成,所以需要用十六進制來表示bytes,這邊直接將`0x5B38Da6a701c568545dCfcB03FcB875f56beddC4`複製即可,輸入好之後按下**transact**按鈕來執行 > 這邊的按鈕之所以是transact這個詞,而非execute之類的,是因為在區塊鏈當中,都是透過發起一筆**交易**,來改變合約狀態的,跟一般網路中的request類似 4. 當交易送出之後,應該可以看到右下角的訊息有更新,且應該是打綠勾的代表成功執行 ![](https://i.imgur.com/BuTTdUw.png) <br/> 到這邊為止,你就已經成功Mint NFT出來了,但是這個NFT現在只能查到tokenId跟owner,還沒有美美的圖片跟trait,owner是`0x5B38Da6a701c568545dCfcB03FcB875f56beddC4`,這邊你可以調用`ownerOf`來去查看`tokenId` 1 的擁有者是誰,結果會顯示`0x5B38Da6a701c568545dCfcB03FcB875f56beddC4`,方法跟上面調用`safeMint`一樣,自己試試看吧! 下一篇我們會針對solidity做一些講解,並為我們的NFT內容做一些更動 若對文章中的內容有些疑惑都歡迎寄信或留言給我 email: fomofox818@gmail.com 這邊也能追蹤我的[Twitter](https://twitter.com/ShileXe) ,拿來記錄一些幹話跟想法用的