作者:師大科技系 PecuLab 蔡芸琤 (Pecu)
根據 https://aptos.dev/tutorials/your-first-nft 的步驟,以及【成為 Aptos 公鏈開發者的第一步】來帶著初學者一步步完成,在 Aptos 上發行第一個 NFT。
因為,RUST SDK 在我撰寫此文的當下,還沒把創建 NFT 需要的 SDK 公開出來,所以,我先以 Typescript SDK 來進行說明。
依照【成為 Aptos 公鏈開發者的第一步】已完成了 aptos-core 專案下載,本文從 https://aptos.dev/tutorials/your-first-nft 中的以下步驟開始進行說明。

官方文件中的第二步,一開始是專案下載,在本文中略過不再重述,直接從如何透過 Typescript SDK 來進行第一個 simple_nft 的例子開始說明。
先重新連上 Docker 環境,前情提要可參考【使用 Move Module 進入 Aptos 智能合約開發的第一步】。

開始測試第一個 simple_nft 的例子,執行成功會看到 Alice 和 Bob 的交易過程被展示出來。
本文所使用的 Docker 環境,與官方文件中要進行的 pnpm 有些許不同,請將 pnpm 更改為 npm 來執行。
依序執行指令如下:
cd ~/aptos-core/ecosystem/typescript/sdk/examples/typescript npm install npm run simple_nft
接著說明這個交易過程的逐步細節以及對應的程式碼。官方文件在這個例子中,為了區別 FT (Fungible Token) 和 NFT,分別使用 Coin 代表 FT,而 Token 代表 NFT。
- 初始化 Representational State Transfer (REST) 和 Aptos 水龍頭。
- 創建兩個帳戶,Alice 和 Bob。
- 從水龍頭為 Alice 和 Bob 的帳戶,分別提供 100000000 個 Coin。
- 在 Alice 的帳戶中創建放置 NFT 的 Collection,並產生第一個 NFT。
- Alice 將這個 NFT 轉給 Bob。
- Bob 透過代理商將這個 NFT 再轉給 Alice。
以上步驟,透過 https://github.com/aptos-labs/aptos-core/blob/main/ecosystem/typescript/sdk/examples/typescript/simple_nft.ts 原始碼所完成,以下的逐步說明,會根據原始碼中的行號來進行對應解釋。
第一步:初始化 Representational State Transfer (REST) 和 Aptos 水龍頭。
請參閱第 15 行至第 16 行,使用 Typescript SDK 來與 Aptos 溝通,確認完成第一步的初始化動作。
第 20 行,建一個 TokenClient 的物件 tokenClient,等著完成第二步之後所需要的常見操作,例如創建 Collection 和 NFT、進行轉移 (transferring)、建立聲明 (claiming)。
第二步:創建兩個帳戶,Alice 和 Bob。
第 27 行至第 28 行,分別建立 AptosAccount 的帳戶物件為 alice 和 bob。
第三步:從水龍頭為 Alice 和 Bob 的帳戶,分別提供 100000000 個 Coin。
第 38 行至 39 行,從水龍頭為 Alice 和 Bob 的帳戶,分別提供 100000000 個 Token。在 Aptos 中,每個 AptosAccount 帳戶物件,都必須具有鏈上的代幣呈現形式 (representation),此段程式利用水龍頭為 Alice 和 Bob 的帳戶領取同質化代幣 (Fungible Token),代表著 Alice 和 Bob 目前的這個帳戶中的 representation 是 Fungible Token。
第四步:在 Alice 的帳戶中創建放置 NFT 的 Collection,並產生第一個 NFT。
因為,第三步創建帳戶時,已經將 representation 指定為 Fungible Token。所以,第 63 行至第 69 行是,在 Alice 的帳戶下,再建立可放入 NFT 的 Collection。一個 Collection 代表著一個容器的概念,其中可以包含零個、一個或多個不同的 NFT 呈現形式。第 73 至第 81 行,是在這個 Collection 下創立 Alice 的第一個 NFT。
這個公版 NFT 是由 Aptos 所提供,透過 https://github.com/aptos-labs/aptos-core/blob/53d3e1675c005771bdcd7b908479e002dd8fe145/ecosystem/typescript/sdk/src/token_client.ts#L90 可看到能填入的 NFT 資訊欄位有哪些,公版 NFT 合約內容可從 https://github.com/aptos-labs/aptos-core/blob/main/aptos-move/framework/aptos-token/sources/token.move 看到。
若要自行創建公版 NFT 之外的合約,就要自行撰寫 Move 發布新合約,再自建跟這張合約互動的 SDK (Typescript SDK, Python SDK, or Rust SDK)。
第五步:Alice 將這個 NFT 轉給 Bob。
第 85 行至第 86 行,先確認 Alice 的 Collection 中的內容物是甚麼。第 90 行至第 96 行,確認 Alice 的帳號中餘額有多少。第 100 行至第 101 行,查閱 Alice 的 Collection 中的 NFT 詳細內容。第 104 行至第 115 行,Alice 將這個 NFT 轉給 Bob。第 119 行至第 127 行,Bob 確認收到 Alice 傳來的 NFT。
第 130 行至第 138 行,查閱這筆轉移結束後,Alice 和 Bob 當前帳戶中的 NFT 數量。
第六步:Bob 透過代理商將這個 NFT 再轉給 Alice。
第 140 行至第 151 行,Bob 透過代理商將這個 NFT 再轉給 Alice。在這邊使用的是 tokenClient.directTransferToken 而不是 Alice 轉移給 Bob 使用的 tokenClient.offerToken,所以,也不需要 Alice 再做一次 tokenClient.claimToken 進行,確認收到 NFT 的動作,就可以直接拿到。
第 154 行至第 163 行,,查閱這筆轉移結束後,Alice 和 Bob 當前帳戶中的 NFT 數量。
Aptos 的思維和以太鏈有甚麼不同?
在這個例子裏面,我發現了以下幾項有趣的不同,以下是在 Aptos 中有的新鮮事。
- 對於每個帳戶中的代幣呈現形式 (representation),會強制要求確認。
- 若要存放 NFT,必須先建立 Collection,代表著一個容器的概念,其中可以包含零個、一個或多個不同的 NFT 呈現形式。
- 透過代理商轉移 tokenClient.directTransferToken,就比較像是在以太坊中的直接轉移的動作。如果是在 Aptos 進行直接轉移 tokenClient.offerToken,收件方需要進行 tokenClient.claimToken 的確認動作。
若有更新的體悟,再來分享給大家,為何 Aptos 要這麼設計。