Solana NFT 開發第二話 製作並發佈 NFT

  • FrankFrank
  • /
  • 30 分鐘閱讀
  • /
  • Jun 3, 2022
  • /
  • - views

上文中我們完成了製作 NFT 的前期開發環境準備,現在就可以準備發佈 NFT 了。

首先準備好一個空的資料夾:

mkdir nft-blank
cd nft-blank

如果你安裝了 VS Code, 此時可以使用 VS Code 打開這個資料夾:

code .

準備CandyMachine的設定文件

Candy Machine 有一個核心的設定文件 config.js ,裡面設定了所有 Candy Machine 的重要參數,可以參考下面這個範例:

{
    "price": 0.3, 
    "number": 10, 
    "gatekeeper": null,
    "solTreasuryAccount": "DEVKXTfCTqEzgyZ98GUvxdW5raRCfMKXm5KxzgyTjRqb", 
    "splTokenAccount": null,
    "splToken": null,
    "goLiveDate": "20 Mar 2022 00:00:00 GMT",
    "endSettings": null,
    "hiddenSettings": null,
    "whitelistMintSettings": null,
    "storage": "arweave-sol",
    "ipfsInfuraProjectId": null,
    "ipfsInfuraSecret": null,
    "awsS3Bucket": null,
    "noRetainAuthority": false,
    "noMutable": false
}  
  • price: SOL 售價
  • number: 發行上限
  • gatekeeper: 防止機器人的相關設定
  • solTreasuryAccount: 收款地址
  • goLiveDate: 指定開售日期
  • endSettings: 指定結束銷售的條件
  • hiddenSettings: 如果希望所有 NFT metadata 都指向固定的 URI, 可以使用這個設定參數來控制
  • whitelistMintSettings: 白名單的控制邏輯
  • storage: 指定 NFT 存儲的空間
  • ipfsInfuraProjectId: 如果使用 IPFS存儲,在這裡指定 infura 的 project id
  • ipfsInfuraSecret: 同上,如果使用 IPFS存儲,在這裡指定 infura 的 secret
  • noRetainAuthority: 如果設定為 true,那每個 NFT 的update authority 將轉移給鑄造者。變相失去了 NFT 的控制權。絕大多數情況下要設定為 false
  • noMutable: 指定 NFT 的metadata 是否可以被更改。

關於設定文件的詳細解釋,可以參考官方資料

首先我們在這篇文章中先完成一個最簡單的 NFT。之後的文章我們再逐步介紹盲盒,白名單,防止機器人等的進階功能。

準備 assets

在當前路徑下建立一個 asset 資料夾:

mkdir assets

這個資料夾中需要存放 NFT 的相關檔案, 格式是 0.json0.png ,json 檔案是 NFT 的 metadata , png 則是 NFT 的圖案。有多少個 NFT,就要準備多少對 json 和 png。

Metadata 的格式如下:

{
  "name": "Number #0001",
  "symbol": "NB",
  "description": "Collection of 10 numbers on the blockchain. This is the number 1/10.",
  "seller_fee_basis_points": 500,
  "image": "0.png",
  "attributes": [
    { "trait_type": "Layer-1", "value": "0" },
    { "trait_type": "Layer-2", "value": "0" },
    { "trait_type": "Layer-3", "value": "0" },
    { "trait_type": "Layer-4", "value": "1" }
  ],
  "properties": {
    "creators": [
      { "address": "N4f6zftYsuu4yT7icsjLwh4i6pB1zvvKbseHj2NmSQw", "share": 100 }
    ],
    "files": [{ "uri": "0.png", "type": "image/png" }]
  },
  "collection": { "name": "numbers", "family": "numbers" }
}

關於 metadata 中的參數解釋,可以參考官方資料

官方提供了一個樣例 assets 方便讀者測試,可以按此下載

驗證 assets

當我們準備好 assets 之後,最好進行進行一下驗證步驟,以免手殘打錯了資料。 我們可以使用 verify_assets 指令,輕鬆進行驗證。

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

如果出現 Cannot find module 等類似的錯誤,請確保你指定了正確的 metaplex 安裝路徑哦。 運行完成後會有如下輸出:

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

Verifying token metadata for 100 (img+json) pairs
Checking manifest file: /Users/frank/solana/assets/0.json
Checking manifest file: /Users/frank/solana/assets/1.json
...
Checking manifest file: /Users/frank/solana/assets/17.json
Checking manifest file: /Users/frank/solana/assets/18.json
Checking manifest file: /Users/frank/solana/assets/19.json
ended at: Sun Jun 05 2022 13:47:08 GMT+0800 (Hong Kong Standard Time). time taken: 00:00:00

如果有驗證錯誤,控制台會有相應的錯誤原因,可以根據指示修改。

進一步驗證 assets

運行完了上面的 verify_assets 指令,基本的格式錯誤已經檢測完畢,理論上已經可以繼續了。但因為這些 metadata json 對於 NFT 至關重要,出錯後不僅影響顯示,而且會影響出售的收益。所以我們在發佈前最好再次檢查 metadata 是否正確。

@levicook 在 hackmd.io 上發佈了一篇文章,裡面有一系列指令可以進一步檢測 metadata json,推薦大家前往一讀, 跟著文章中的步驟再檢測一次。

確認無誤後,便可準備將 assets 上載發佈了。

建立並上載Candy Machine

萬事俱備,只欠 upload。

現在可以使用如下指令上載我們的傑作了。

ts-node ~/metaplex/js/packages/cli/src/candy-machine-v2-cli.ts upload -e devnet -k ~/.config/solana/DEVKXTfCTqEzgyZ98GUvxdW5raRCfMKXm5KxzgyTjRqb.json -cp config.json ./assets

其中 -k 後的參數是指定使用的錢包,這個錢包的產生上一篇文章有提到過。 -cp 後的參數是指定設定檔案,就是本文頭部所述的那個。最後的 ./assets 自然就是指定裝載 json 和圖像的資料夾,candy machine 會在這個步驟將資料夾內的 json 和圖片檔案上載到 arweave 中。

注意,這個過程中可能會出現錯誤,candy machine 允許我們「斷點續傳」,即遇到錯誤可以重新上載,程式會自動緊接上次繼續上載。

當上載完成後,控制台會顯示 candy machine 的 address 等重要資料:


wallet public key: DEVKXTfCTqEzgyZ98GUvxdW5raRCfMKXm5KxzgyTjRqb
(node:45002) ExperimentalWarning: buffer.Blob is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
WARNING: On Devnet, the arweave-sol storage option only stores your files for 1 week. Please upload via Mainnet Beta for your final collection.

Beginning the upload for 10 (img+json) pairs
started at: 1654522026597
initializing candy machine
Candy machine address:  31JY8szaKFFh2JzjvFvXL5KWL6k9cRyNXgFTqJbxz4MD
Collection metadata address:  52BntZ1rFWQ6XomG2u65rEL9chmijzsQDGPtFabGotRe
Collection metadata authority:  DEVKXTfCTqEzgyZ98GUvxdW5raRCfMKXm5KxzgyTjRqb
Collection master edition address:  2GihorhxXdagqex8wmWopnBg2ymdvgorFfGzMeBnw3AL
Collection mint address:  Ca6RmDVxmFn7TV2VHvrx3JotESrw3fomG7eYGAdjfY7P
Collection PDA address:  DpdSrm3wvBbSejc6c1VxRF3EUcQp2bWvEUq2LD4Y9Zu8
Collection authority record address:  EPNquPuJqtUvpLf4MUgPEdsXqopJDViHiMPrG2jgUid3
Collection:  {
  collectionMetadata: '52BntZ1rFWQ6XomG2u65rEL9chmijzsQDGPtFabGotRe',
  collectionPDA: 'DpdSrm3wvBbSejc6c1VxRF3EUcQp2bWvEUq2LD4Y9Zu8',
  txId: 'YB4ChhPTwRFkFNqGcABgJLa6LoRjhLnfa9yJbLdySUVK4tgG5WBvKe3Xi9qUso9u8KpXCtaiNHqZ6ruYWJGoArj'
}
initialized config for a candy machine with publickey: 31JY8szaKFFh2JzjvFvXL5KWL6k9cRyNXgFTqJbxz4MD
[0] out of [10] items have been uploaded
Starting upload for [10] items, format {"mediaExt":".png","index":"0"}
Saved bundle upload result to cache.
Computed Bundle range, including 10 file pair(s) totaling 0.218MB.
Processing file groups...
Progress: [████████████████████████████████████████] 100% | 10/10
Uploading bundle via Bundlr... in multiple transactions
0.00008592 SOL to upload 0.440MB with buffer. Sending fund txn...
Successfully funded Arweave Bundler, starting upload
Progress: [████████████████████████████████████████] 100% | 30/30
Bundle uploaded!
Saved bundle upload result to cache.
Upload done. Cleaning up...
Writing all indices in 1 transactions...
Progress: [████████████████████████████████████████] 100% | 1/1
Done. Successful = true.
ended at: 2022-06-06T13:27:51.177Z. time taken: 00:00:44

上面控制台列出的各種地址,都需要妥善保存起來,今後會用到。其中最重要的:

Candy machine address:  31JY8szaKFFh2JzjvFvXL5KWL6k9cRyNXgFTqJbxz4MD

這個地址便是我們 candy machine 的地址了。

驗證上載的檔案

上一步上載完成後,我們可以進而進行驗證,確保上載的資料正確無誤。

留意上一步完成後,在當前目錄下會產生一個 .cache 資料夾,裡面會有一個 json 檔案,<網路名稱>-temp.json ,裡面記錄了 candy machine 的相關資料。這個 json 檔案中我們要找到 cacheName 部分,這個在下面的驗證環節需要用到。

得到 cacheName 之後,就可以執行驗證:

ts-node ~/metaplex/js/packages/cli/src/candy-machine-v2-cli.ts verify_upload \
    -e devnet \
    -k ~/.config/solana/DEVKXTfCTqEzgyZ98GUvxdW5raRCfMKXm5KxzgyTjRqb.json \
    -c temp

上面的 -c 後面的參數就是上面提到的 cacheName 哦。

ts-node ~/metaplex/js/packages/cli/src/candy-machine-v2-cli.ts verify_upload \
    -e devnet \
    -k ~/.config/solana/DEVKXTfCTqEzgyZ98GUvxdW5raRCfMKXm5KxzgyTjRqb.json \
    -c temp
wallet public key: DEVKXTfCTqEzgyZ98GUvxdW5raRCfMKXm5KxzgyTjRqb
uploaded (10) out of (10)
ready to deploy!

驗證成功喇!

Mint NFT

至此,我們的 candy machine 已經接近完成了。現在可以透過 mint_one_token 指令來鑄造 NFT 喇:

ts-node ~/metaplex/js/packages/cli/src/candy-machine-v2-cli.ts mint_one_token \
    -e devnet \
    -k ~/.config/solana/DEVKXTfCTqEzgyZ98GUvxdW5raRCfMKXm5KxzgyTjRqb.json \
    -c temp


wallet public key: DEVKXTfCTqEzgyZ98GUvxdW5raRCfMKXm5KxzgyTjRqb
(node:59487) ExperimentalWarning: buffer.Blob is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
Transaction size estimate:  1074
mint_one_token finished 3gz8h53yYt6vbZurEkcbUGmwVE2GM7aYq1yM8Nn861M8w7Hg3Wrbqv6xnzGL4G9RDYTmQ5MtdA3YskvyHsCsgAvr

可以看到我們已經成功鑄造了一個 NFT 。在 solscan 上輸入上面的 trx hash, 在 Token Balance Change 中就可以看到喇。

在 Phantom 錢包中也可以看到哦!

這裡有個小插曲,我們看到在 Phantom Wallet 中顯示的 NFT 的系列名稱為 Collection NFT,而不是我們 Meta Data 中指定的名稱,這個是怎麼回事呢? 大家不妨自己先研究一下,之後的文章會講到。

下一篇文章,我們將會快速搭建一個 Minting Website,來和我們的 Candy Machine 交互。