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 撰写。