Web3新手系列:探索使用Solana 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 那樣)
會輸出下面的日志:
其中的 69yXraTu3FqXZkATg6MiRnWT2qHd4tRzWsfCHHE9j2XE 經常會被稱作 Mint Address,也是我們所創建的 Token 的 ID。
Token 地址為:
https://solscan.io/token/69yXraTu3FqXZkATg6MiRnWT2qHd4tRzWsfCHHE9j2XE?cluster=devnet
創建 Token Account
接下來我們需要為上一步創建的 Token 創建一個 Token Account。
mint
在跟其他錢包地址 mint 新 Token 之前,讓我們先嘗試一下為上一步創建出的 Token Account mint 一個 Token unit。只需要輸入:
會輸出下面的日志:
或者也可以:
也可以嘗試一下 mint 其他數值,例如 1.9 :
查看交易詳情,會發現:由於我們在第一步創建 Token 時指定「 --decimals 」為 0 ,所以實際執行 mint 時,會舍去小數部分,於是 mint 的量將依然是 1 。
也可以嘗試一下直接給一個錢包地址 mint token,這裏使用 4wztJ4CAH4GbAUopZrVk7nLvoAC3KAF6ttMMWfnBRG1t 來演示:
為錢包地址 mint
上面的 mint 操作的目標是 Token Mint Address,而按照我們最初的設想,應該給其他不屬於我們的錢包地址 Mint。
接下來,讓我們使用 Web3 用戶的錢包地址來完成上面的 mint 步驟。
-
Token 我們直接使用上面的 69yXraTu3FqXZkATg6MiRnWT2qHd4tRzWsfCHHE9j2XE
-
Wallet Address:使用 4wztJ4CAH4GbAUopZrVk7nLvoAC3KAF6ttMMWfnBRG1t
但我們直接簡單的替換參數的時,卻會得到意外的結果:
地址是存在的,只是 Mint 所需要的地址並不是原始的錢包地址,而是需要與之關聯的 Token Account。
我們需要進行與上面相同的流程:給錢包地址創建 Token Account,然後使用創建出的 Token Account mint 新的 Token unit。
換句話說,如果我們想要為某個錢包地址鑄造一個 Token unit,那么我們就必須先為這個錢包地址創建一個 Token Account。至於為什么需要這樣做,其中一個原因是我們並沒有權限直接修改某個地址的數據。
在 Solana 的文檔中,有時候你會分別看到兩個相似的概念:代幣账戶(Token Account)和 關聯代幣账戶(Associated Token Account,ATA)。文檔中看起來兩者似乎有些關聯,但是卻並沒有說明這一點,這非常讓人困惑。
不過如果你查看 Metaplex 的文檔,就會發現它很明確的指出:“關聯代幣账戶,有時會被簡稱為代幣账戶”。
我們這裏不對這兩者進行深入研究,只需要想象代幣账戶是代幣和錢包地址之間的媒介。
我們使用下面的命令,為錢包地址創建一個 Token Account:
重復創建將會報錯:
在日志中也能看出,由確定的 Mint Account 和 錢包地址派生出的 Token Account 是確定的(3JocyxV4LX4VbNU248CvNozZphgRW5JTyxn7FPWrF8bx),只是由於已經存在了,所以才打印了錯誤信息。
獲取 Token Account
我們需要通過 RPC 接口,獲取某個錢包地址是否有 Mint 過我們創建的 NFT。具體來說,通過「 getTokenAccountsByOwner 」方法來查詢數據。下面是接口需要的參數:
你需要將「 _YOUR_RPC_PROVIDER_ 」替換為你自己選擇的 RPC 供應商提供的地址。
可以使用 Solana 官方提供的地址,或者,可以在這裏找到公共的免費 RPC 網絡: https://zan.top/service/public-rpc/solana
注意:公共地址可能不穩定,如果需要穩定的 RPC 服務,建議創建自己的 API Key。
對於上面的錢包地址來說,具體就是這樣:
除了通過代碼手動填充請求參數之外,也可以使用 @solana/web3.js 中提供的 Connection 上的「 getParsedTokenAccountsByOwner 」方法,其內部實際上就是通過創建 Connection 時提供的 RPC 接口調用了「 getParsedTokenAccountsByOwner 」method。
如果是一個已經創建過 Account 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 項目
所有選項均使用默認值:
為了快速开始,我們直接使用 @ant-design/web3-solana 來連接錢包,使用 @solana/spl-token 和 Token Program 交互。
添加相關的依賴:
我們需要包括首頁的 3 個頁面,創建 app/sign-in/page.tsx 和 app/sign-on/page.tsx。它們分別用於連接錢包並檢查用戶是否已經注冊(是否 mint NFT),以及讓用戶進行注冊流程(mint NFT)。
打开演示頁面後,首先看到的是歡迎語,以及前往 Sign in 頁面的鏈接:
進入頁面後,您需要先去 Sign in:
點擊「Continue with Solana」,將會喚起錢包
而如果你之前並沒有注冊,則會提示你先去注冊:
這是因為在 /api/sign-in 的邏輯中,會根據連接的錢包地址查找關聯的 Token Account。由於我們之前並沒有使用過,所以自然找不到數據,於是系統就會認為這個錢包地址並沒有注冊過。
然後我們按照提示,來到 Sign on 頁面,注冊頁面與登錄頁面大體上類似,只是在服務端的處理邏輯不同:
其實可以將兩個邏輯合並,這裏分开只是為了便於演示。
無論如何,讓我們點擊「Start with Solana」,連接錢包。然後,如果順利的話,會看到成功的提示:
讓我們來到 Solscan 中,看看發生了什么。進入 https://solscan.io/?cluster=devnet,查詢你的錢包地址。或者,也可以查看這個地址:79reVF46NyuuH7PADR3i6RpQ7hmBZgYkiieXNYPM1oLF
有一條交易數據:
注意在 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 撰寫。
鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播信息之目的,不構成任何投資建議,如有侵權行為,請第一時間聯絡我們修改或刪除,多謝。
星球日報
文章數量
8007粉絲數
0