---
# System prepended metadata

title: 連小學生都能懂的智能合約開發-開始來寫你的第一個NFT(1)

---

# 連小學生都能懂的智能合約開發-開始來寫你的第一個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) ，拿來記錄一些幹話跟想法用的


