本篇文章更新時間:2022/03/26
如有資訊過時或語誤之處,歡迎使用 Contact 功能通知。
一介資男的 LINE 社群開站囉!歡迎入群聊聊~
如果本站內容對你有幫助,歡迎使用 BFX Pay 加密貨幣新台幣 贊助支持。


繼前篇 [Solana] 公鏈上從發幣(Fungible Token)到上架交易所(DEX)的方法 筆記如何發行「同質代幣」後,就是要輪到大家比較熟悉的「非同質化代幣」筆記了。

說起來 Solana 的文件裡的 Token Program 其實就已經把「如何發行 NFT」方法寫完。而且其實文件從上看到下就會發現 NFT 就只是符合: 不可分割(沒有小數點單位)與 Token 供應量為一個,這兩個條件的 一般代幣(Token)

這概念與以太坊(ETH)的 EIP-721 NFT 定義的標準不太一樣。 Solana 區塊鏈上沒有去預先定義 Token 的形式,就是 智能合約 與 Token ,只是由於 ETH 是這一切運作概念的元老,文件也寫得很清楚其定義,後人自然也是在前人種樹的情況下受惠。

延伸閱讀以太坊發行 NFT 的相關文章: 使用 REMIX,OPENZEPPELIN 15 分鐘建立 NFT 智能合約使用 REMIX,OPENZEPPELIN 15 分鐘建立 NFT ERC 1155 智能合約介面化發行 NFT 的雲端工具 thirdweb

那 Solana 上的 NFT 還缺少什麼?

如同前一篇筆記,發行完代幣後,雖然可以轉帳,但還有一個很根本的問題:可讀性。

到底這一串像密碼的代碼是什麼?為此就還有延伸的 Meta 中繼資料要補充,像是給這個代碼一個代幣名稱、代幣描述、代幣分類、專案連結...等,NFT 發行也不例外。

因為 Solana 並沒有像 ETH 有自己的 Token 類型定義描述的中繼 Meta 資料,它開放給社群透過一個智能合約標準來處理: Metaplex ,非公鏈自己定義交給社群來發揮是滿有趣的一件事,目前看起來 Solana 官網上的 NFT 頁面是已經公開支持這個標準以及主流錢包 Phantom 也實作展示 NFT 的功能了。

Metaplex 實作了鑄造 Mint Token 的功能到制定了 Token Meta 的中繼資料,最後還有交易行為(Royalties 版稅)與其他新功能正在開發中。Metaplex 不只是開發這套強大的智能合約系統,還包含了創作者工具,讓創作者可以透過使用這些開源工具輕鬆辦到發佈 NFT 的功能,專注創作。

Focus on the artwork, not writing a new smart contract. The Solana NFT standard and minting program offers extreme customizability, with ecosystem-wide support.

Metaplex 的 GitHub 專案 裡很豐富,提供了「適合大量發行的指令發行 NFT 模式工具 Candy Machine」、「介面發行 NFT 的工具 Storefronts」與「獨立銷售(mint)NFT 的網站範本」。

本文筆記主要大量發行 NFT 使用的工具是使用 Metaplex Candy Machine v2

發行 NFT 的前置作業需求

  1. 基本指令工具的操作經驗(Git 與前篇安裝的 Solana 指令工具)
  2. 安裝下列工具到作業系統(我使用的是 macOS Monterey 12.3 Intel CPU)
  3. 注意安裝環境的版本
  4. 耐心...

這章節尤其重要,因為網路上有不少相關教學,但從使用的環境到最後使用的工具都有一些時間與版本(Candy Machine v1 已經棄用)的落差。這導致過程 一定 很有可能出錯。

先說我安裝的工具版本: solana-cli 1.9.13, git version 2.32.0 (Apple Git-132), NodeJS v16.13.0, NPM v8.1.0, Yarn v1.22.18, ts-node v10.7.0

NodeJS 相關套件都使用 NVM 工具管理

其實 官方的教學文件 算滿完整了,基本上都可以直接照著操作。我這邊就是列一個自己處理的過程,有些內容就直接建議對照文件來處理。

如果這篇文章與現行版本差距很大,也建議照官方文件操作,這邊就是大概筆記主要流程。

先使用 Git 把專案建立在當前使用者目錄下

git clone https://github.com/metaplex-foundation/metaplex.git ~/metaplex

然後安裝專案必要相依套件

yarn install --cwd ~/metaplex/js/

第一步到這邊我就碰到一個錯誤XD

如果碰到 node-gyp build faild 問題

  1. 先砍掉 ~/metaplex/js/ 下的 node_module 目錄
  2. npm install canvas
  3. yarn install (沒錯誤的話就不用後面步驟)
  4. npm install @solana/web3.js (執行過程提示我少了這個套件就裝這個套件)
  5. npm install @types/node (原因同上)

確認安裝 Candy Machine v2 成功:

ts-node ~/metaplex/js/packages/cli/src/candy-machine-v2-cli.ts --version

會正確顯示版本,當前 0.0.2

到這邊就算是把環境處理好了!

設定 Candy Machine v2

開始設定之前也不免的要先確認接下來想執行的網路環境,文件裡是使用開發網路(devnet)來進行。我則是直接使用主網(mainnet-beta)來實測(好孩子不要學),不要虧到錢的關鍵很簡單,就是錢包裡不要放太多錢XD ( 0.1 $SOL 就很夠玩了)

如何產生 Solana 錢包地址跟轉帳(或空投)這篇就列為基本須知不再多贅述,這段就是提示到「注意你當前作業的網路環境狀態是正式的主網還是測試的開發網路」。

關於 Candy Machine v2 (下稱 CMv2)建立時的參數可以參考文件 說明。

建立一個資料夾 ~/chun_nft ,裡面放置 config.json 的 CMv2 設定檔案,內容如下:

{
    "price": 0.01,
    "number": 1,
    "gatekeeper": null,
    "solTreasuryAccount": "2TSWP4dKBTqpDVmjh2WD8DYN1oPe6G6ZGqBnVxTntR61",
    "splTokenAccount": null,
    "splToken": null,
    "goLiveDate": "25 Dec 2021 00:00:00 GMT",
    "endSettings": null,
    "whitelistMintSettings": null,
    "hiddenSettings": null,
    "storage": "arweave-sol",
    "ipfsInfuraProjectId": null,
    "ipfsInfuraSecret": null,
    "nftStorageKey": null,
    "awsS3Bucket": null,
    "noRetainAuthority": false,
    "noMutable": false
}

設定收款帳號的 pubkey 跟 NFT 數量與價錢還有開放銷售時間等基本(最少)參數後,再來就是準備你的圖片和描述檔案。

建立資料夾 ~/chun_nft/assets 裡面放置 0.png, 0.json 編號從 0 開始,我只打算鑄造 1 張,所以就是這樣一組。如果要多張的話就是接續 1,2,3,...

0.json 的內容如下:

{
    "name": "Chun #01",
    "symbol": "ATGYPFP",
    "description": "一介資男頭貼珍藏",
    "seller_fee_basis_points": 500,
    "image": "0.png",
    "attributes": [{
        "trait_type": "Country",
        "value": "Taiwan"
    }, {
        "trait_type": "Gender",
        "value": "Male"
    }],
    "properties": {
        "creators": [{
            "address": "MXPTWMCbZPFNwEv4XFg84QCeokJSLD392JS8dirMdwg",
            "share": 100
        }],
        "files": [{
            "uri": "0.png",
            "type": "image/png"
        }]
    },
    "collection": {
        "name": "numbers",
        "family": "numbers"
    }
}

就是簡單描述以及設定這個 NFT 的屬性質,一般來說增加好玩的特性都是在屬性質上有所差異,像是某個屬性質取得難度為 1/100 之類的低機率,來凸顯這個 NFT 的價值。

如果想參考這個描述檔案 官方文件 也有提供一組,可以自行取用。

驗證圖庫資源

在建立好的 ~/chun_nft 目錄中執行指令:

ts-node ~/metaplex/js/packages/cli/src/candy-machine-v2-cli.ts verify_assets ./assets

注意提示,確保這樣的圖片與描述檔案都正確。

建立 Candy Machine v2 並上傳圖庫

確認指令在 ~/chun_nft 目錄中執行,且目錄中包含 config.json 檔案與驗證過的圖庫資源。

ts-node ~/metaplex/js/packages/cli/src/candy-machine-v2-cli.ts upload -cp config.json ./assets -k /Users/chun/.config/solana/id.json -e mainnet-beta --rpc-url https://solana-api.projectserum.com -c example

不指定環境 -e 會預設 devnet,指定後也不建議使用主網預設的 RPC 位置,我這邊去拿請求數相對少的 Serum 的 RPC (偷吃步

-c 的快取參數其實也是必要,值可以自行指定,不然後面執行其他指令也會出錯。(踩過雷了)

文件裡提示不建議用主網的 RPC 端點來操作是真的用主網就會發生請求數過多被 Block 的問題,但說實在,建立一個 RPC 端點也不簡單捏~ 真的一般人可以嗎!? 哈

由於建立 CMv2 會需要準備一些燃料,所以也確保自己戶頭裡的 $SOL 還夠量。

For a 10k collection, the rent costs are approximately 16.7 SOL. This scales linearly with the number of items in your collection. Thus, you can get an approximate on chain rent cost estimate by multiplying the number of items in your collection by 0.00167 SOL.

雖然要準備燃料,但也真的不多,所以我也才敢用主網來測試。

指令執行結果:

wallet public key: 2TSWP4dKBTqpDVmjh2WD8DYN1oPe6G6ZGqBnVxTntR61
USING CUSTOM URL https://solana-api.projectserum.com
(node:39523) ExperimentalWarning: stream/web is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
(node:39523) ExperimentalWarning: buffer.Blob is an experimental feature. This feature could change at any time
Beginning the upload for 1 (img+json) pairs
started at: 1648104398951
initializing candy machine
Candy machine address:  AfezKuTg1Zj9X1ZyDihuV8uYmSdrgUETze1Uxr5tzs7Q
Collection metadata address:  57YfQcyusrPxughTmgBSK3vfaoCKhSZJ7hUZuFRQbWVo
Collection metadata authority:  2TSWP4dKBTqpDVmjh2WD8DYN1oPe6G6ZGqBnVxTntR61
Collection master edition address:  9MgUji3u9Au8wXJ3cBj8m6SYZ3fPtjEvg23NDmQMWhTV
Collection mint address:  5814prdXxU8L8tm5QozuKMVRMq2g2CZi1U7wtAsSapbH
Collection PDA address:  2E5wQa4oHofjNFUQ3Vjo8DwTLRdDT4kr4Jo2eFwGz6x1
Collection authority record address:  GeuicufGA9ZKLa2o1Lq12SyhtpgBk5HnBEDxX7L8qffi
Collection:  {
  collectionMetadata: '57YfQcyusrPxughTmgBSK3vfaoCKhSZJ7hUZuFRQbWVo',
  collectionPDA: '2E5wQa4oHofjNFUQ3Vjo8DwTLRdDT4kr4Jo2eFwGz6x1',
  txId: '5YS2AQoeN137qz2BFoa9CkoyRTy5BCYxSntE98teuy4kgMR5NZnCHZ9xvpib5BMAEbtmduGtQ9fcFmXkFihc7Ubm'
}
initialized config for a candy machine with publickey: AfezKuTg1Zj9X1ZyDihuV8uYmSdrgUETze1Uxr5tzs7Q

上傳中的訊息

Starting upload for [1] items, format {"mediaExt":".png","index":"0"}
Saved bundle upload result to cache.
Computed Bundle range, including 1 file pair(s) totaling 0.127MB.
Processing file groups...
Progress: [████████████████████████████████████████] 100% | 1/1
Uploading bundle via Bundlr... in multiple transactions
0.000031237 SOL to upload 0.149MB with buffer. Sending fund txn...
Successfully funded Arweave Bundler, starting upload
Progress: [████████████████████████████████████████] 100% | 3/3
Bundle uploaded!
Saved bundle upload result to cache.
Upload done. Cleaning up...
Waiting 5 seconds to check Bundlr balance.
Requesting a withdrawal of 0.000005885 SOL from Bundlr...
Successfully withdrew 0.000010885 SOL.
Writing all indices in 1 transactions...
Progress: [████████████████████████████████████████] 100% | 1/1
Done. Successful = true.

這邊使用的 Bundlr 服務很有意思,前面 config.json 描述檔案裡對儲存空間的選用預設是 arweave-sol ,也就是可以透過 Bundlr 來支付 $SOL 上傳到 Arweave 去中心化儲存的區塊鏈裡。支付完成後這工具會幫你出金剩餘款項!(不過有時候會 timeout...

Mint 一個 NFT 給自己吧!

先確認當前自己帳號的狀態

spl-token accounts

Token                                         Balance
---------------------------------------------------------------
5814prdXxU8L8tm5QozuKMVRMq2g2CZi1U7wtAsSapbH  1
8A6hLUHLD1nRen4nivUCLP3QoX4pfFpr9yqPvr5vpLT6  1
FV66ygXAXXs556MQrofx89y2WUGt4G1NWBXL9BZGi7kF  9972000000

然後使用 mint_one_token 來鑄造一個 NFT 給自己

ts-node ~/metaplex/js/packages/cli/src/candy-machine-v2-cli.ts mint_one_token -cp config.json ./assets -k /Users/chun/.config/solana/id.json -e mainnet-beta --rpc-url https://solana-api.projectserum.com -c example

wallet public key: 2TSWP4dKBTqpDVmjh2WD8DYN1oPe6G6ZGqBnVxTntR61
USING CUSTOM URL https://solana-api.projectserum.com
(node:43074) ExperimentalWarning: stream/web is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
(node:43074) ExperimentalWarning: buffer.Blob is an experimental feature. This feature could change at any time
Transaction size estimate:  1074
mint_one_token finished 2dt9yijEJADXExoVtfJ3AuBytBW4dkfeYTZEWPVRWWEiQXmGaF9JKeUwt1NMmQTznmbo5tP7BjEN1NX6rQXHTYRn

再次查看帳號狀態 spl-token accounts

Token                                         Balance
---------------------------------------------------------------
2CnXNqpKnrDyMMEVzzWdc4NLnFbFPUMNGpnHmfE1S4ox  1
5814prdXxU8L8tm5QozuKMVRMq2g2CZi1U7wtAsSapbH  1
8A6hLUHLD1nRen4nivUCLP3QoX4pfFpr9yqPvr5vpLT6  1
FV66ygXAXXs556MQrofx89y2WUGt4G1NWBXL9BZGi7kF  9972000000

指令的 -c 快取參數要指定,不然這部分執行時會噴 TypeError: Cannot read properties of undefined (reading 'program') 這個錯誤

鑄造出來後就可以到 Solscan 上觀察: Chun #01 (ATGYPFP)

Phantom 錢包裡的樣子

建立銷售網站 Minting Website (candy-machine-ui)

到前面章節的步驟其實就已經算是完成 NFT 後端系統建置,不過這樣還不夠,也還不是最完整,包含出金沒用完的 $SOL 以及簽署 NFT 等操作如果要完整的流程還是要對照文件來繼續操作,本章節僅針對大方向關鍵流程筆記。接著「如果要對外獨立銷售就會需要一個網站介面讓人使用」需求建置銷售網站。

將操作目錄切換到 ~/metaplex/js/packages/candy-machine-ui

同樣這個 Metaplex 專案裡提供了銷售網站的範本,採用 ReactJS 框架開發。

先複製環境參數檔案 .env.example.env 然後編輯內容如下:

REACT_APP_CANDY_MACHINE_ID=AfezKuTg1Zj9X1ZyDihuV8uYmSdrgUETze1Uxr5tzs7Q

REACT_APP_SOLANA_NETWORK=mainnet-beta
REACT_APP_SOLANA_RPC_HOST=https://api.mainnet-beta.solana.com/
SKIP_PREFLIGHT_CHECK=true

REACT_APP_CANDY_MACHINE_ID 這邊就是剛剛上傳圖資時建立的那個 Candy machine address: AfezKuTg1Zj9X1ZyDihuV8uYmSdrgUETze1Uxr5tzs7Q

這個環境 .env 檔案也是描述之後銷售的參數,所以記得自己使用的網路是主網還是開發網路。

建立 candy-machine-ui 時,我使用說明文件的指令 yarn install 會出錯,所以改 npm install 然後再跑一次 yarn install && yarn start

完成環境建置後看到的網站畫面很簡單,就是選擇 Solana 錢包工具登入、鑄造對話筐這樣而已。

因為只發行一張而且被我 mint 完了,所以狀態就顯示為「已售光」啦~

後續剩下就是自己補上其他主視覺與文案等設計的部分,幫到這邊算很友善了!

建置創作者工具與銷售整合平台 Metaplex Storefront

這工具可以讓創作者透過網站介面操作來發行自己的 NFT ,算是相對前面指令操作的簡單版本。

切換目錄到 ~/metaplex/js,然後 yarn install && yarn bootstrap 安裝相依套件。過程沒問題,但我啟動時出錯 Error: Cannot find module 'is-plain-object'TypeError: isPlainObject is not a function ,這時候就是

npm install is-plain-object

安裝缺少的套件繼續就可以 yarn start

打開瀏覽器輸入網址: http://127.0.0.1:3000/ 就可以看到「Init store」字眼,確定選擇好右上角的網路環境(主網 或 開發網路)後,點下去初始化這套工具。

特別注意的還是 RPC 節點問題,由於會對節點有大量請求,這邊也是建議要自行建置節點來處理。

文件 裡還有更多其他部署與客製化的說明,值得一看!

後記

其實整體看下來流程真的不多,花比較多時間的是踩雷與找資料解決問題。有經驗後會快一點!所以整篇會特別把錯誤部分寫出來。網路上那堆教學怎麼這麼順,文件也寫得好像不會出錯似的,但...我怎就這麼坎坷啊?XDD

多一點這些方便的工具讓創作者願意切入市場是好事,工具始終就是工具,要能傳達到到真正價值,還是需要降低點難度。

延伸參考資料

  1. Solana and Metaplex FAQ
  2. How To Create a Solana NFT With IPFS
  3. 查看 Metaplex Token Meta 資料的方法
  4. MintUI - An extensible UI for creating Metaplex Candy Machines
  5. PixelCatz NFT 專案
  6. QuickNode 付費節點架設服務

Share:

作者: Chun

資訊愛好人士。主張「人人都該為了偷懶而進步」。期許自己成為斜槓到變進度條 100% 的年輕人。[///////////____36%_________]

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *


文章
Filter
Apply Filters
Mastodon