Solana NFT 開發第四話 白名單

  • FrankFrank
  • /
  • 17 分鐘閱讀
  • /
  • Jun 5, 2022
  • /
  • - views

Solana Candy Machine 的白名單模式,相比 EVM 生態中的白名單略顯奇怪。至少我第一次接觸到的感覺是這樣。

Solana Candy Machine 的白名單,是透過發放給白名單用戶一個特殊的 SPL Token,藉此作為鑄造 NFT 的「許可證」。擁有這個 SPL Token 的用戶,則可以在白名單階段使用 SPL Token 來鑄造 NFT。

因此,使用白名單的大致步驟如下:

  • 建立白名單 SPL Token
  • 將白名單 SPL Token 發放給指定用戶
  • 設定並更新 Candy Machine 使用白名單功能
  • 白名單用戶使用 SPL Token 鑄造 NFT

建立白名單 SPL Token

為了方便識別,我們採用一個新的 Key Pair 來建立白名單 SPL Token:

solana-keygen grind --starts-with WLT:1

Searching with 8 threads for:
	1 pubkey that starts with 'WLT' and ends with ''
Wrote keypair to WLTTJqBDVuWJRtpR9FnLmHV5jhBLGANA9zThoZLNVYy.json

然後使用這個 WLT 字頭的 Key Pair 來建立 SPL Token:

spl-token create-token --decimals 0 --url devnet WLTTJqBDVuWJRtpR9FnLmHV5jhBLGANA9zThoZLNVYy.json

Creating token WLTTJqBDVuWJRtpR9FnLmHV5jhBLGANA9zThoZLNVYy

Signature: 3F274okGHftmYXAjPQBVDc9REkYxmn9mbkTBsrFqTAKKKiVWp1csfefF32SsQB3cTGLqSwkVyMs9ZRmSqVAKh1ze

建立 SPL Token 後,接著建立 Token Account:

spl-token create-account WLTTJqBDVuWJRtpR9FnLmHV5jhBLGANA9zThoZLNVYy --url devnet
Creating account 827kMvguv5zoSYU8xokyzWdmuvbgBZWR2hJKxzYeBKiE

Signature: 2a29jLdEaPmNVBemK9Ty91LxFrLiJyWKenbTCG3oLevLToj7pXcgxyrTeQ27D3TArLig6vPQ6YZEmC9kbcQ4DXGt

到這裡先暫停一下,不知道你會不會和我當初一樣有些困惑,create-token 在做什麼? Token Account 又是什麼? 如果有,不妨往下看,若是沒有興趣,可以跳過。

在 Solana 的世界中,智能合約 ( Programs ) 不能儲存數據。所有鏈上數據,都是存儲在一個個 「Account」 中。

我們使用 create-token 指令,就是和現有的 token program 交互,建立了一個新的 Mint Account。 這個 Mint Account 中記錄了這個 SPL Token 的基本資料,類如誰能夠鑄造這個Token,誰能夠凍結這個 Token,總共有多少供應量, Token 有多少數位等資料。 Mint Account 僅僅記錄這個 SPL Token 本身的資料, 但不包含「賬本」,即不包含誰擁有多少 Token 這個資料。

Token Account, 則是上面 SPL Token 的「賬本」, 記錄著:

  • Token Account 的擁有者是陳大文
  • 陳大文 擁有100個 Token
  • 陳大文 授權 陳小文 可以使用陳大文的 16 個 Token

每一個 SPL Token, 都對應著千千萬萬個 Token Account,我們可以在 solscan 中輸入 Mint Account 的地址來查看對應的 Token Account。

好,廢話說完,明白了 Token Account 是什麼之後,我們就要鑄造一些 SPL Token 以做白名單之用。 透過 spl-token mint 指令,即可鑄造 SPL Token:

spl-token mint WLTTJqBDVuWJRtpR9FnLmHV5jhBLGANA9zThoZLNVYy 100 --url devnet 

Minting 100 tokens
  Token: WLTTJqBDVuWJRtpR9FnLmHV5jhBLGANA9zThoZLNVYy
  Recipient: 827kMvguv5zoSYU8xokyzWdmuvbgBZWR2hJKxzYeBKiE

Signature: 4pruix4WgwCWwZsWAgEHbA55TpRcEa2U1v8Pih6nXnSEWbwRABanWCGANqcreSZaLyTht6kWuM9m5rQzH8y5hLPe

完成後,檢查餘額:

spl-token accounts --url devnet

Token                                         Balance
---------------------------------------------------------------
WLTTJqBDVuWJRtpR9FnLmHV5jhBLGANA9zThoZLNVYy   100

給白名單用戶分發 SPL Token

透過 Transfer 處理

分發 Token, 可以透過普通的 Token Transfer 方式處理:

spl-token transfer <TOKEN_ADDRESS> <TOKEN_AMOUNT> <RECIPIENT_ADDRESS or RECIPIENT_TOKEN_ACCOUNT_ADDRESS> --config <PATH>

spl-token transfer WLTTJqBDVuWJRtpR9FnLmHV5jhBLGANA9zThoZLNVYy 1 4zHCvFuRfRwJSbLkBJWdwU2ceYmsQ5EZKk6EGZspRpzs --url devnet --fund-recipient

透過 Gumdrop 處理

Gumdrop 的好處是,可以將 SPL Token 分發給大量的用戶,用戶可以前往指定網址自行領取 SPL Token,從而節省主動 Transfer 時的大量 gas 消耗。

安裝 Gumdrop

截止撰文當日,gumdrop 僅支援 Node 14.17.6 ,如果更高版本的 NodeJS 暫時未能支援。因此如果需要使用 gumdrop,需要安裝指定版本的 NodeJS。 否則會出現下面的錯誤:

Error: Debug Failure. False expression: Non-string value passed to ts.resolveTypeReferenceDirective

確認 Node 版本正確,就可以繼續了:

git clone https://github.com/metaplex-foundation/gumdrop
cd gumdrop
yarn install --network-timeout 100000  <-- 這個可能需要一段時間
yarn bootstrap

安裝完成後,我們需要準備白名單地址列表檔案。 建立一個 whitelist.json 檔案,內容如下:

[
  {
    "handle": "<USER WALLET>",
    "amount": 1
  },
  {
    "handle": "<USER WALLET>",
    "amount": 2
  },
]

然後,我們要選擇一個初始錢包,並轉入一定量的白名單 SPL Token:

spl-token transfer WLTTJqBDVuWJRtpR9FnLmHV5jhBLGANA9zThoZLNVYy 100 DEMgMtEAA1spKrRVKurxRBFZptZu7AZjZ8J9QuThdR1c --url devnet --fund-recipient

然後,就可以建立 Gumdrop 了:

ts-node ~/gumdrop/packages/cli/src/gumdrop-cli.ts create \
  --env "devnet" \
  --keypair "/Path/To/DEMgMtEAA1spKrRVKurxRBFZptZu7AZjZ8J9QuThdR1c.json" \
  --rpc-url "https://api.devnet.solana.com" \
  --claim-integration "transfer" \
  --transfer-mint "WLTTJqBDVuWJRtpR9FnLmHV5jhBLGANA9zThoZLNVYy" \
  --distribution-method "wallets" \
  --otp-auth "disable" \
  --distribution-list "/Path/to/whitelist.json"

其中,--keypair 是上面已經被轉入 SPL Token 的錢包 Key Pair , --transfer-mint 則是 SPL Token 的 Mint Account, 留意所有路徑都需要使用絕對路徑。

完成後會在當前路徑產生一個 .log 資料夾,裡面會找到一個 urls.json ,在裡面會見到不同地址對應的 URL, 打開這個 URL,用戶即可以連接錢包後按「Claim」取得 白名單 SPL Token。

Candy Machine 白名單設定

完成上面的步驟之後,最後也是最重要的一步,我們需要更改 Candy Machine 的設定,以便讓 Candy Machine 支援白名單功能。

打開 Candy Machine 的設定檔案,在 whitelistMintSettings 中加入如下設定:

"whitelistMintSettings": {
    "mode" : { "burnEveryTime": true }, --> 指定每次使用後會是否銷毀 Token
    "mint" : "WLTTJqBDVuWJRtpR9FnLmHV5jhBLGANA9zThoZLNVYy",  --> 白名單 Token 地址
    "presale" : true, --> 是否開啟允許白名單用戶在公開發售之前鑄造 
    "discountPrice" : 0.123 --> 設定不同的 Mint 價格
}

完成後,我們需要更新 Candy Machine 設定:

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

wallet public key: DEVKXTfCTqEzgyZ98GUvxdW5raRCfMKXm5KxzgyTjRqb
update_candy_machine finished 21HHtsq5gcSDrzMXT8KQGc29NdfhRBJZZ51zGoEL7s6YkQ1WaV4tmiGzHcA9hPKRuchuQVX4F6o7xoowCCJQhvza

更新後可以看到,只有擁有白名單 Token 的錢包可以鑄造,而沒有白名單 Token 的錢包則無法鑄造。

另外,鑄造時也可以見到,除了要消耗 SOL 之外,也需要消耗白名單 Token。

至此,我們就完成了具有白名單功能的 NFT。 掌聲鼓勵!下一篇文章,將介紹另一個進階功能 - 盲盒模式。