Solana Web3.js 是一個功能非常豐富的JavaScript 函式庫,在今年11 月正式發表了2.x 版本。相較於1.x,新版本變化比較大,這篇文章嘗試對其主要變化做一些概括。

目前由於2.x 版本剛發布,使用量並不高,很多使用量很高的函式庫也沒有切換。不過我們可以先了解一下,為未來的遷移做好準備。

版本對比

不得不承認,舊版使用起來其實更簡單。首先,舊版其實只有一個套件:@solana/web3.js 所有內容都在它裡面。並且它基於類,封裝了大量常用的操作。例如Connection 類,它帶有數十種方法,基本上將開發者所想要的功能涵蓋了。而且Solana cookbook 中提供了大量的範例程式碼,開發者總是能從這裡找到自己需要的東西。

但是,這也造成了另一些問題:雖然開發者實際上使用到的功能,往往只佔其中的一小部分,但是最終整個程式碼庫都會被下載到使用者的裝置上。由於整個庫的程式碼量很大,這可能會持續一小段時間。

反觀2.x 版本,官方團隊將原有的程式碼庫拆分為了幾個很小的模組組成,例如@solana/accounts、@solana/codecs、@solana/rpc、@solana/signers、@solana/transactions等。並且放棄了基於類別的實現,更多的採用單一函數,這在JavaScript 程式碼建置時的最佳化很有幫助,DApp 沒有使用到的程式碼將會被刪除,實際上不會被下載到使用者裝置上。根據官方文件的統計,使用新版的DApp 基本上都能得到30% 的尺寸優化,如果只用到了很小一部分功能,那麼能得到更高的優化比例( https://solana-labs.github.io/ solana-web3.js/#statistics )。

這對Solana 團隊的文件水平帶來了考驗,如何讓開發者迅速找到需要的功能,將是一個重要的事項。不過目前看來,至少包名具有不錯的語意性,從名字上就能大概知道它們可以用來做什麼。這應該能從一定程度上減少開發者遷移的難度。

當然,由於其剛發布不久,所以很多項目還沒有進行遷移。 Solana Cookbook 上,2.x 版本的範例也比較少。而由於新版本傾向於使用執行時間內建功能(例如產生金鑰對),文件中卻缺少對這裡的描述,導致有些地方讓開發者有些無所適從。

2.x 還有一個很重要的特點:零依賴。這一點可能對許多用戶來說並不重要,但從今年12 月初發生在@solana/web3.js 1.95.5 和1.95.6 版本上的供應鏈攻擊來看,更多的外部輸入和依賴會急速增加安全事件發生的可能。而隨著2.x 版本的發布,Web3.js 的開發團隊決定應該更多的使用本機的功能,而取消外部依賴和Polyfills 的引入。以後可能會有變化,但至少目前來說,2.x 版本消除了所有外部依賴。

重要變更點

連接

如上文所介紹的,1.x 有大量方法透過Connection 來提供。不過其最主要的功能,還是用於透過設定RPC 請求位址,建立一個請求發送器。然後透過它來發送各種請求。

在2.x 中,則是透過更函數式的方式來實現:

Web3 新手系列:現在升級 @solana/web3.js 2.x 開啟函數式編程

在上述程式碼中,當我們呼叫「sendAndConfirmTransaction」來傳送交易時,會自動發起HTTPS 請求,並且建立一個WSS 連接,訂閱交易狀態,在交易被確認後返回交易hash。

密鑰對

公鑰和私鑰相關的地方也有很大變化。在1.x 版本最常用的Keypair 和PublicKey 兩個類別不存在了,被成一些函數取代。

例如可以使用「await generateKeyPair()」產生金鑰對,在之前則是直接透過「Keypair.generate()」產生一個金鑰對。

你可能注意到新的generateKeyPair 回傳了Promise,而不是想之前那樣,可以直接傳回所需的金鑰對。這是由於新的實作盡可能的利用了JavaScript 的Web Crypto API,使用了原生的Ed25519 實作。 Web Crypto API 的許多方法都是非同步的。不過這一點變化倒是並非不能接受,在2024 年即將結束的今天,JavaScript 開發者們早已將Promise 看作非常熟悉的朋友了。

發送交易

1.x 的使用者應該很熟悉「 Transaction」和「VersionedTransaction」兩個類,當我最開始了解Solana 時,它們之間的關係也曾經讓我非常疑惑。

在2.x 版本中,同樣不再有這兩個類別。

舊版中提供的System Program 相關方法也不再繼續存在,所以「SystemProgram」類別上的靜態方法都需要從另外的地方引入。

例如“transfer”指令,需要呼叫“@solana-program/system”中的“getTransferSolInstruction”函數。

由於不再提供class,Web3.js 提供了函數式程式設計的能力中常用的「 pipe 」形式。下面透過pipe函數來實現原本1.x 的轉帳功能:

Web3 新手系列:現在升級 @solana/web3.js 2.x 開啟函數式編程

能夠發現交易不再透過Connection 來發起,而是透過我們定義的RPC Provider,產生一個獨特的函數,然後呼叫該函數來發起交易。相對1.x 版本來說,程式碼量有些增加,不過優點是可自訂性更強了。

交易透過HTTPS RPC 發起,然後透過訂閱WSS RPC 來確認交易結果。可以感受到新的方式非常依賴WSS,相信以後WSS 的應用將會越加廣泛,這也確實對RPC 供應商的服務穩定性提出了更高的要求。如果你正在尋找一個可靠的WSS 節點供應商,ZAN Node ( https://zan.top/home/node-service?chInfo=ch_WZ )是一個不錯的選擇。作為Solana 在亞太地區的領先服務商,我們致力於提供穩定、高效的連接效能。除了Ethereum 和Solana 等熱門鏈外,我們還支援超過20 條主流鏈的RPC 服務,以滿足不同場景的需求。

React

有趣的是,@solana/web3.js 專案中還包含了一個名為@solana/react 的函式庫,提供了一些React Hook,內建了諸如signIn 等功能。

總結

@solana/web3.js 2.x 版本的發布,充分體現了Solana 團隊對於不斷發展和改進的承諾。為開發人員提供一個高效、靈活、可自訂的與Solana 網路互動的方式,並有助於推動該平台的採用和發展。

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