以太坊 JavaScript 库:web3.js 与 ethers.js 比较(第一部分)

Web3.js 和 ethers.js 都是 JavaScript 库,其作用是使开发者可以与以太坊区块链交互。这两个库都很实用,都能满足大多数以太坊开发者的需求。本文将重点围绕 web3.js 和 ethers.js 的相同点和不同点来对它们进行比较,以便您能更好地理解它们的细微区别。本文的目的是帮助开发者理解两个库的优缺点,以便能够决定哪个库适合其具体用例。本文中提供了一些资源,可能对刚接触区块链开发或一般编程的用户有用。

TL;DR:两个库都有用。对于您的用例而言,可能有一个库更加适合。

Web3.js 拥有一个与以太坊基金会相关的用户和维护者社区。它提供实用的 API 参考。从大约 2015 年开始,它在许多项目中被广泛使用。因此,该库已经成为许多“构建去中心化应用新手入门”教程的“必备资源”。

Ethers.js 的优势之处在于紧凑小巧,同时又包含大量测试案例。它提供实用的“新手入门”文档,因此新用户也可使用。许多开发者评价 ethers.js 使用起来“简单”、“直观”,并且该库在近两年越来越受欢迎,下载量和在项目中的使用量也不断增加。

什么是 web3.js?

web3.js 库是由以太坊基金会构建的开源 JavaScript 库(GNU Lesser General Public License 第 3 版),包括通过 JavaScript 对象表示法 - Remote Procedure Call (JSON-RPC) 协议与以太坊节点进行通信的函数。也就是说,它是一个支持开发者与以太坊区块链进行交互的 JavaScript 库。Web3.js 最新版本为 1.2.9,在本文中将引用该版本。Web3.js 由四个模块组成。

什么是模块?

在 JavaScript 中,模块是在更大的程序中具有特定功能的代码。模块应该具有独立性,即如果将某个模块从库、程序或应用中移除,整个库、程序或应用应该不会停止运行。熟悉 python 或 java 的用户可能也熟悉“类”,它与模块类似。FreeCodeCamp 对 JavaScript 模块进行了详细解释,对于刚接触 JavaScript 的用户有用。

web3.js 由哪些模块组成?

Web3.js 有一个主类,称为 web3。在该类中可以找到该库的大多数功能。组成 web3js 的另外 5 个模块分别是:

  1. web3-eth
  2. web3-shh
  3. web3-bzz
  4. web3-net
  5. web3-utils

web3-eth 有什么作用?

web3-eth 模块中包含函数,其作用是使 web3.js 的用户可以与以太坊区块链进行交互。具体来说,这些函数能够与智能合约、归外部所有的账户、节点、挖出的区块以及交易进行交互。下面显示了三个说明性示例:

  • web3.eth.getBalance 的作用是获得指定区块的某个地址的以太坊余额
  • web3.eth.signTransaction 的作用是对交易签名
  • web3.eth.sendSignedTransaction 的作用是将签名的交易发送到以太坊区块链。

web3-shh 有什么作用?

web3-shh 模块的作用是使您可以与 Whisper 协议进行交互。Whisper 是一个消息传输协议,其目的是轻松广播消息以及进行低层异步通信。下面显示了两个说明性示例:

  • web3.shh.post 将 whisper 消息发布到网络
  • web3.shh.subscribe 创建传入的 whisper 消息订阅

web3-bzz 有什么作用?

web3-bzz 模块的作用是使您可以与 Swarm 交互。Swarm 是一个去中心化存储平台和内容分发服务,它可以用来为去中心化应用存储图片或视频等文件。下面显示了两个说明性示例:

  • web3.bzz.upload 的作用是使您可以将文件和文件夹上传到 Swarm
  • Web3.bzz.download 的作用是使您可以从 Swarm 下载文件和文件夹

web3-net 有什么作用?

web3-net 模块的作用是使您可以与以太坊节点的网络属性进行交互。通过 web3-net,您可以采用您需要获得的信息所关联的协议后加 .net(在这里使用 * 指定,表示选择 web.eth.net、web3.shh.net 或 web3.bzz.net)来查找该节点的相关信息。下面显示了两个说明性示例:

  • web3.*.net.getID 返回网络 ID
  • web3.* .net.getPeerCount 返回连接到节点的对等点数

web3-utils 有什么作用?

web3-utils 模块为您提供实用程序函数,这些函数可在以太坊去中心化应用以及其他 web3.js 模块中使用。实用程序函数可以重复使用,使代码编写更轻松,在 JavaScript 和其他编程语言中很常见(请参阅由 Dave Flanagan 编写的 JavaScript:权威指南,第 6 版,其中介绍了 JavaScript 的 JQuery 库中存在的实用程序函数)。Web3-utils 包含实用程序函数,这些函数用于转换数字、验证值是否满足特定条件以及搜索数据集。下面显示了三个说明性示例:

  • web3.utils.toWei 将以太转换为 Wei
  • web3.utils.hexToNumberString 将十六进制值转换为字符串 web3.utils.isAddress,校验特定字符串是否为有效的以太坊地址。

什么是 ethers.js?

Ethers.js 是一个 JavaScript 库,其作用是使开发者可以与以太坊区块链进行交互。该库包含 JavaScript 和 TypeScript 中的实用程序函数,以及以太坊钱包的所有功能。Ethers.js 的最新版本为 5.0.3。Ethers.js 是通过 Ethers 创建的,是采用 MIT 许可证的开放源。

与 web3.js 相似,ethers.js 有四个模块,构成应用程序编程界面 (API)。

  1. Ethers.provider
  2. Ethers.contract
  3. Ethers.utils
  4. Ethers.wallets

ethers.provider 有什么作用?

Ethers.provider 的作用是提取与以太坊区块链的连接。它可以用于签发查询和发送已签名的交易,这将改变区块链的状态。下面显示了三个说明性示例:

  • ethers.providers.InfuraProvider 的作用是使您可以与 Infura 托管的以太坊节点网络建立连接
  • ethers.provider.getBalance 将为您获取区块链中某个地址或区块的以太坊余额
  • ethers.provider.resolve 将解析传递到以太坊地址的以太坊名称服务 (ENS) 名称(通过“承诺”— 如果您刚接触 JavaScript,我们建议您阅读有关承诺的更多内容,它们的作用是在未来某个时间点对它们进行计算时可以返回数据)。

注:web3.js 也有服务于此目的的提供商,位于 web3 基础模块中。Ethers.js web3.js 的组织方式截然不同,因此尽管两个库的功能非常相似,但模块间并非总是能清晰对应。

ethers.contract 有什么作用?

Ethers.contract 的作用是部署智能合约并与它交互。具体来说,该模块中的函数用于侦听从智能合约发射的事件、调用智能合约提供的函数、获取有关智能合约的信息,以及部署智能合约。下面显示了两个说明性示例:

  • ethers.ContractFactory.fromSolidity 从 Solidity 编译器的编译器输出或从 Truffle 生成的 JSON 文件创建一个用于部署智能合约的“工厂”。ethers.Contract 使您可以与已部署的智能合约进行交互。

ethers.utils 有什么作用?

Ethers.utils 提供用于格式化数据和处理用户输入的实用程序函数。Ethers.utils 的作用方式与 web3-utils 相似,能够简化去中心化应用的构建流程。下面提供了三个示例:

  • ethers.utils.getContractAddress 从用于部署智能合约的交易中提取智能合约地址
  • ethers.utils.computeAddress 通过传递与地址相关的公钥或私钥的函数来计算地址ethers.utils.formatEther 将所传递的 Wei 金额转换为 Ether 十进制字符串格式

ethers.wallet 有什么作用?

Ethers.wallet 提供的功能与我们目前讨论过的其他模块截然不同。Ethers.wallet 的作用是使您可以与现有钱包(以太坊地址)建立连接、创建新钱包以及对交易签名。下面提供了三个示例:

  • ethers.wallet.createRandom 将创建随机新账户。
  • ethers.wallet.sign 将对交易签名并将已签名的交易返回为十六进制字符串的形式(通过“承诺”— 如果您刚接触 JavaScript,我们建议您阅读有关承诺的更多内容,它们的作用是在未来某个时间点对它们进行计算时可以返回数据)。
  • ethers.wallet.getBalance 将为我们提供钱包地址的以太坊余额。

Web3.js 在 web3.eth 模块中有一个类似的包,称为 web3.eth.accounts。但是,在该包的文档中有如下说明:“该包未经审核,可能不安全。在用于生产环境之前,请注意妥善清除内存,安全存储私钥,并适当测试交易接收和发送功能!”

我如何确定在去中心化应用中到底应该使用 web3.js 还是 ethers.js 呢?两者有何区别?

首先,如果您要创建样板应用或完成教程,则使用该样板或教程建议您使用的库,不管是 web3.js 还是 ethers.js。这将为您省去不少麻烦,让您可以更好地跟着教程操作。请务必使用教程指定的 web3.js 或 ethers.js 版本。有许多教程没有更新,因此不要想当然地认为您可以使用最新版本的库,除非教程中具体说明。

如果您要从零开始构建应用并确定需要使用的库,则我们调整了一个软件评估流程。Andres Canal 在其文章“Using Quill,js to Build a WYSIWYG Editor for your Website”中使用该流程来评估需要使用哪个文本编辑器。

下面列出了 9 个问题。您(即读者)在确定哪个库适合您时应该思考这些问题。此外还提供了一些上下文和信息以帮助您回答这些问题。

1.) 库的受欢迎程度有多重要?

借用 Andres Canal 的定义:

“在 Github 上受欢迎的项目正如您所料。也就是说,有许多人提问、参与和支持。这些活动能让软件更加可靠。通过查看任何一个项目的星星数、已发布的问题数量、处理中的拉取请求以及项目的参与者数量,可以确定它的受欢迎程度。”

截止到撰写本博客时,Web3.js 获得了近 8,800 颗星,而 ethers.js 获得了近 1,500 颗星。在 GitHub 上使用 web3.js 的资源库有 51,300 个,而使用 ethers.js 的有 18,500 个。Web3.js 存在的时间更长,这也是 web3.js 更受欢迎的原因之一。

2.) 库的维护有多重要?

我们希望自己使用的库能够频繁更新,以修复错误和添加新功能。尽管不完美,但通过查看一两个月期间的提交数、已解决的问题数、正在处理的问题数以及维护者数,可了解开源项目的优势和弱点。用户从中也能看到库的维护模式,了解库一般有哪些更新并修复了哪些错误,并以此作为判断库维护情况的代理指标。我们来查看两个库(web3.jsethers.js)在 GitHub 上的每月动态,以了解它们的统计数据。

ethers.js 的维护者只有一人 — Richard Moore,他完成的提交数和已解决的问题数相当惊人,值得称赞。Web3.js 有 12 位维护者,绝大多数提交数都是由其中三人完成的。在这方面没有明显的胜负差异,但在选择库时应注意,这些统计数据可以帮助您确定,在维护性方面您最看重哪些,并根据您的需求确定库的优先性。

3.) 库的开发负责人是谁?使用库的项目有多少个?

Web3.js 是以太坊基金会的一个项目。以太坊基金会是一个非营利性组织,致力于协议层开发的研究和组织。Ethers.js 的目的是建立“一个完整、简单、小巧的库,取代 web3 和 ethereum.js”。Ethers.js 的开发者是 Richard Moore,并由他来创建和维护库。

有些项目公开声明了他们使用的是哪个库,我们认为从这些数据中可以看出两个库受欢迎的程度都很高。查看 web3.jsethers.js 依赖图,以了解您信任的项目使用的是哪个库,或者他们是否同时使用/支持两个库。

4.) 库具有测试有多重要?

如果预编写的测试对您的项目来说很重要,那么从历史数据来看,ethers.js 胜。截至撰写本文时止,Ethers.js 已经在 Github 上发布了 3.0 发行版的清晰测试文档,但还没有为 5.0 发行版更新该文档。Web3.js在测试文档方面稍逊一筹。如果ethers.js在接下来几周更新测试文档,那么在测试和测试文档方面将继续保持优胜地位。到目前为止尚无定论,因为 ethers.js 它测试套件至今似乎还未更新。

5.) 库的下载量有多重要?

由于 web3.js 存在的时间更长,因此它的下载量(截至 5 月 20 日止为 14,703,432 次)超过了 ethers.js 的下载量(截至 5 月 20 日止为 8,500,336 次),但是如果查看周下载量,ethers.js(截至 5 月 20 日止为 184,798 次)超过了 web3.js(截至 5 月 20 日止为 175,661 次),因此目前的下载次数更加频繁。Ethers.js 的近期下载量更高,而 web3.js 的总下载量更高。

6.) Web 性能有多重要?

如果 web 性能对您来说非常重要,则我们认为 ethers.js 库的性能更加优越。ethers.js 库声称未压缩大小为 284 kb,而在 NPM 上列出的解压缩大小为 3.5 MB。Web3.js 至少大一个数量级,解压缩大小为 10.6 MB。考虑到 ethers.js 比 web3.js 更加小巧,因此推测使用 ethers.js 的应用程序比使用 web3.js 的相同应用程序加载速度更快。这是因为不管使用什么库,它都会和构成 web 应用程序的其他资源一起加载。我们没有使用 web3.js 和 ethers.js 分别对完全相同的应用程序测试加载速度,因此在这一点上应该持保留态度。如果数据量大小对应用程序会有影响,则数据量较小的 ethers.js 库会有优势。

7.) 文档质量有多重要?

文档质量是一个主观性指标,但评估文档质量的其中一种方式是阅读文档,看它的阅读难易程度如何。最理想的情况是,编写的文档能够让新用户理解如何使用库。文档在结构安排上也应该能够让资深用户快速找到他们需要查找的内容。

Web3.js 具有广泛而相当实用的 API 参考。这是文档最重要的部分。“新手入门”材料非常简单。这可能会深受资深用户的欢迎,但适合 web3.js 新用户使用的材料很少。

Ethers.js 包括“新手入门”部分以及拓展性 API 参考。这些材料非常实用,使得 ethers.js 相对于 web3.js 具有优势,尤其是对以太坊生态系统中的入门级开发者而言。针对 ethers.js 的文档中有一些不完整的部分,这对用户来说很不方便(“以太坊基本介绍”部分以及以前对开发者非常实用的常见代码样例“整理合集”尚未更新到 5.0,用户必须返回到第 4.0 版文档查找这些有用的资源)。Ethers.js 还清晰地介绍了使用 ethers.js 的优势。

两个库的文档都存在不足之处,因此如果文档对您来说很重要,请花一些时间来了解并确定哪个库提供了充分的信息来帮助您实现您需要构建的特性。

8.) 库的总使用量有多重要?

由于 web3.js 存在的时间更长,因此具有更高的下载量和 GitHub 星星数,而 ethers.js 在受欢迎程度上有所上升。最终应该由您自己来决定库的哪些方面对您的用例最重要。

9.) 许可证有多重要?

根据您的具体用例,开源软件许可证对您来说可能很重要。Web3.js 有 LGPLv3 许可证(列在 NPM 上,但没有列在其 GitHub 库上),ethers.js 有 MIT 许可证(列在其 GitHub 库上)。联系关于该主题的法律专家可以获取有关许可证的更多详细信息。但是,Slava Todavchich 在文章“了解开源和免费软件许可”中针对该主题进行了生动有趣的阐述。

结论

正如我们开篇就已指出,两个库都能够完成任务。Ethers.js 在近两年来越来越受欢迎,下载量和项目使用量都不断增加。Web3.js 一直以来都作为标杆存在,并且仍然拥有许多开发者共享资源。

请关注第二部分。我们将发布一份跟进教程,介绍如何连接到 Infura API 并使用 web3.js ethers.js 发送翻译。

非常感谢 Thomas HayAkua Nti Sean Brennan 对本指南的编写做出的广泛贡献。有关更多 Web3 教程,请参阅 Infura 博客 ConsenSys Academy

查看我们的开发者文档,以了解通过与 Infura 交互来读取和写入以太坊数据的不同方法。您是 Infura 的新用户?注册并立即免费开始使用!