Web3新手系列:探索使用Solana Token登錄

avatar
ZAN Team
2天前
本文約2243字,閱讀全文需要約3分鐘
NFT (non-fungible token) 作為一個正如其名字所指的「不可替代」的代幣,非常適合用於作為一種身份認證工具。

NFT (non-fungible token) 作為一個正如其名字所指的「不可替代」的代幣,非常適合用於作為一種身份認證工具。

接下來,讓我們透過一個簡單的例子,來探索使用NFT 作為註冊憑證的可行性。

前言

在開始之前,先讓我來介紹接下來會用到的工具。

SPL Token

我們可以自己從零開始編寫新的Solana 合約,但對於我們目前想要達到的目的來說,可以直接使用Solana 提供的通用實作:Token Program。

Token Program 屬於Solana Program Library(SPL,https://spl.solana.com/)的一部分,SPL 中提供了包括Token、Swap、Memo 的多個常用程序實現,並且提供了完善的客戶端庫、CLI等工具,極大的方便了Solana 開發者。

Token Program 的專案原始碼位於:https://github.com/solana-labs/solana-program-library/tree/master/token/program

Solana Playground

Solpy (https://beta.solpg.io/) 提供了一個線上編寫和部署Solana 合約的環境,並且預設包含了一些常用的工具,上一節介紹的SPL Token 也在其中。可以讓我們透過spl-token-cli 方便的建立並管理Token。

Auth Token

在這部分,我們會創建一個NFT Token。如果用戶Mint 了Token,那麼就認為這個錢包地址已經在我們的系統中註冊了,反之則提示用戶先進行註冊。

現在,我們先開始On-chain 部分:

建立Token

我們使用spl-token 來創建一個新的token,並且,透過「 --decimals 」來指定它是一個不可分割的Token(就像NFT 那樣)

Web3新手系列:探索使用Solana Token登錄

會輸出下面的日誌:

Web3新手系列:探索使用Solana Token登錄

其中的69yXraTu3FqXZkATg6MiRnWT2qHd4tRzWsfCHHE9j2XE 常會被稱為Mint Address,也是我們所創建的Token 的ID。

Token 地址為:

https://solscan.io/token/69yXraTu3FqXZkATg6MiRnWT2qHd4tRzWsfCHHE9j2XE?cluster=devnet

建立Token Account

接下來我們需要為上一個步驟建立的Token 建立一個Token Account。

Web3新手系列:探索使用Solana Token登錄

mint

在跟其他錢包位址mint 新Token 之前,讓我們先試試看為上一個步驟建立的Token Account mint 一個Token unit。只需要輸入:

Web3新手系列:探索使用Solana Token登錄

會輸出下面的日誌:

Web3新手系列:探索使用Solana Token登錄

或者也可以:

Web3新手系列:探索使用Solana Token登錄

也可以試試mint 其他數值,例如1.9 :

Web3新手系列:探索使用Solana Token登錄

查看交易詳情,會發現:由於我們在第一步創建Token 時指定“ --decimals ”為0 ,所以實際執行mint 時,會捨去小數部分,於是mint 的量將依然是1 。

也可以試試看直接給一個錢包位址mint token,這裡使用4wztJ4CAH4GbAUopZrVk7nLvoAC3KAF6ttMMWfnBRG1t 來示範:

Web3新手系列:探索使用Solana Token登錄

為錢包位址mint

上面的mint 操作的目標是Token Mint Address,而按照我們最初的設想,應該給其他不屬於我們的錢包地址Mint。

接下來,讓我們使用Web3 用戶的錢包位址來完成上面的mint 步驟。

  • Token 我們直接使用上面的69yXraTu3FqXZkATg6MiRnWT2qHd4tRzWsfCHHE9j2XE

  • Wallet Address:使用4wztJ4CAH4GbAUopZrVk7nLvoAC3KAF6ttMMWfnBRG1t

但我們直接簡單的替換參數的時,卻會得到意外的結果:

Web3新手系列:探索使用Solana Token登錄

地址是存在的,只是Mint 所需要的地址並不是原始的錢包地址,而是需要與之關聯的Token Account。

我們需要進行與上面相同的流程:為錢包位址建立Token Account,然後使用已建立的Token Account mint 新的Token unit。

換句話說,如果我們想要為某個錢包位址鑄造一個Token unit,那麼我們就必須先為這個錢包位址建立一個Token Account。至於為什麼需要這樣做,其中一個原因是我們並沒有權限直接修改某個位址的資料。

在Solana 的文件中,有時你會分別看到兩個相似的概念:代幣帳戶(Token Account)和關聯代幣帳戶(Associated Token Account,ATA)。文件中看起來兩者似乎有些關聯,但是卻並沒有說明這一點,這非常令人困惑。

不過如果你查看Metaplex 的文檔,你會發現它很明確的指出:「關聯代幣帳戶,有時會被簡稱為代幣帳戶」。

我們這裡不對這兩者進行深入研究,只需要想像代幣帳戶是代幣和錢包地址之間的媒介。

我們使用下面的指令,為錢包位址建立一個Token Account:

Web3新手系列:探索使用Solana Token登錄

重複建立將會報錯:

Web3新手系列:探索使用Solana Token登錄

在日誌中也能看出,由確定的Mint Account 和錢包位址衍生出的Token Account 是確定的(3JocyxV4LX4VbNU248CvNozZphgRW5JTyxn7FPWrF8bx),只是因為已經存在了,所以才印製了錯誤訊息。

取得Token Account

我們需要透過RPC 接口,取得某個錢包地址是否有Mint 過我們創建的NFT。具體來說,透過「 getTokenAccountsByOwner 」方法來查詢資料。下面是介面需要的參數:

Web3新手系列:探索使用Solana Token登錄

你需要將「 _YOUR_RPC_PROVIDER_ 」替換為你自己選擇的RPC 供應商提供的位址。

可以使用Solana 官方提供的位址,或者,可以在這裡找到公共的免費RPC 網路: https://zan.top/service/public-rpc/solana

注意:公共位址可能不穩定,如果需要穩定的RPC 服務,建議建立自己的API Key。

對於上面的錢包位址來說,具體就是這樣:

Web3新手系列:探索使用Solana Token登錄

除了透過程式碼手動填入請求參數之外,也可以使用@solana/web3.js 中提供的Connection 上的「 getParsedTokenAccountsByOwner 」方法,其內部實際上就是透過建立 Connection 時提供的RPC 介面呼叫了「 getParsedTokenAccountsByOwner」method。

如果是已經建立過Account Token 的錢包,則會回傳:

Web3新手系列:探索使用Solana Token登錄

刪掉了對我們無用的數據

實現

透過上面的嘗試,可知我們能夠運用現有的能力實現我們想要的功能。那麼接下來,就開始編寫客戶端程式碼。

以下程式碼都在https://github.com/gin-lsl/my-sol-token-auth-example

可以在這裡預覽:https://my-sol-token-auth-example.vercel.app/

我會透過建立一個簡單的Nextjs 專案來實現它,使用Ant Design Web3 來Connect Wallet:

初始化Nextjs 項目

Web3新手系列:探索使用Solana Token登錄

所有選項均使用預設值:

Web3新手系列:探索使用Solana Token登錄

為了快速開始,我們直接使用@ant-design/web3-solana 來連接錢包,使用@solana/spl-token 和Token Program 互動。

新增相關的依賴:

Web3新手系列:探索使用Solana Token登錄

我們需要包含首頁的3 個頁面,建立app/sign-in/page.tsx 和app/sign-on/page.tsx。它們分別用於連接錢包並檢查用戶是否已註冊(是否mint NFT),以及讓用戶進行註冊流程(mint NFT)。

打開演示頁面後,首先看到的是歡迎語,以及前往Sign in 頁面的連結:

Web3新手系列:探索使用Solana Token登錄

進入頁面後,您需要先去Sign in:

點擊“Continue with Solana”,將會喚起錢包

Web3新手系列:探索使用Solana Token登錄

而如果你之前並沒有註冊,會提示你先去註冊:

Web3新手系列:探索使用Solana Token登錄

這是因為在/api/sign-in 的邏輯中,會根據連接的錢包位址尋找關聯的Token Account。由於我們之前並沒有使用過,所以自然找不到數據,於是系統就會認為這個錢包地址並沒有註冊過。

然後我們依照提示,來到Sign on 頁面,註冊頁面與登入頁面大致上類似,只是在服務端的處理邏輯不同:

其實可以將兩個邏輯合併,這裡分開只是為了方便示範。

Web3新手系列:探索使用Solana Token登錄

無論如何,讓我們點擊“Start with Solana”,連接錢包。然後,如果順利的話,會看到成功的提示:

Web3新手系列:探索使用Solana Token登錄

讓我們來到Solscan 中,看看發生了什麼。進入https://solscan.io/?cluster=devnet,查詢你的錢包位址。或者,也可以看看這個位址:79reVF46NyuuH7PADR3i6RpQ7hmBZgYkiieXNYPM1oLF

有一筆交易數據:

Web3新手系列:探索使用Solana Token登錄

注意在Instructions 中,能看出交易內部執行了CreateAccount 指令,點選連結進入詳情,會發現它所建立的就是一個TokenAccount:EXfDYkHw3UQw2VqiSLsRAfLMsxkgqnd3nhxbB4V5HAvA。其中的isOnCurve 值為False,表示是沒有私鑰的關聯帳戶。

回到之前的頁面,前往Portfolio -> NFTs,就能看到我們剛才在sign-on 內部所做的Mint 操作,以及Mint 的那個NFT:

總結

讓我們來總結一下整個流程。我們使用spl-token-cli 創建了一個NFT,然後,把一個錢包地址是否有Token Account 並且Mint 過Token 來判斷是否在我們的網站註冊過。

當Web3 使用者連接錢包時,我們會自動往後端發送sign-on,在內部會建立Token Account,並且Mint 一個Token unit,作為使用者已註冊的憑證。

以後,用戶就可以拿同樣的錢包地址再次登入我們的網站了。

本文由ZAN Team(X 帳號@zan_team )的gin-lsl 撰寫。

原創文章,作者:ZAN Team。轉載/內容合作/尋求報導請聯系 report@odaily.email;違規轉載法律必究。

ODAILY提醒,請廣大讀者樹立正確的貨幣觀念和投資理念,理性看待區塊鏈,切實提高風險意識; 對發現的違法犯罪線索,可積極向有關部門舉報反映。

推薦閱讀
星球精選