JavaScript中利用Ethereum网络的两个主要库:Web3js和Ethers

382 阅读9分钟

Ethers与Web3

Web3js和Ethers是在JavaScript中利用Ethereum网络的两个主要库。两者有不同的方式与智能合约互动并处理网络上的交易。

这种差异导致一个处理某些类型的任务比另一个更好。在这篇文章中,读者将了解它们的区别,它们的最佳使用案例,以及它们如何与网络互动。

前提条件

为了获得本文的全部好处,读者需要具备以下条件。

  • 对JavaScript和Node.js有一定的了解。
  • 对Web3、智能合约和区块链有基本了解。

基本主题

本文将涉及的基本主题包括。

Web3JS

这是一个JavaScript库的集合,用于与Ethereum网络互动。这种互动可以是将Ethereum从一个地址发送到另一个地址,也可以是与智能合约进行互动。该网络由计算机(节点)组成,它们共同处理通过网络进行的交易。

这个网络可以是一台电脑上的私人节点,也可以是公共主网,或者是测试网。私人节点和测试网用于开发。测试网是一个更公开的开发场所,对整个世界开放。而公共节点则只限于一台电脑。然而,主网是所有真正的互动发生的地方,也是更有价值的加密货币停留的地方。

EthersJS

这是一个轻量级的JavaScript库,用于与Ethereum智能合约互动,并通过网络进行交易。这个库的目的主要是与ethers.io(一个web3浏览器)一起使用,因此,尺寸很小,现在已经发展到更通用,可以像web3库一样使用。

区块链

这是一个存储和记录数据的系统。区块链由区块组成,这些区块被连接起来形成一条链。这些区块用于存储数据,并可以与链上的其他区块连接。区块链是不可改变的。这意味着,区块本身不能改变,你只能添加新的区块来更新链。

智能合约

这些是在区块链网络上存储和运行的自执行程序。它们是通过向网络发送一种特殊类型的交易来创建的。一旦它们被部署,它们就会为我们的项目创建接口来进行互动。

它们被开发人员用来创建无服务器的前端应用程序。在网络上执行计算任务会变得非常昂贵。因此,我们总是建议所有的计算应该在网络之外进行,只有数据存储才会发生在网络上。

安装

要安装Web3JS库或EthersJS库,我们需要在终端运行它们各自的命令。首先,我们将在终端中打开我们的项目文件夹,然后输入以下任何一个命令来安装这两个包。

npm install web3@1.7.1

或者。

npm install ethers@5.5.4

比较

虽然这两个库可以做同样的操作,但它们都有不同的使用方式,这使得它们在不同的情况下有不同的优势和劣势。

创建代码的大小

EthersJS库的建立是为了简单、轻量和高效。当我们使用Ethers而不是Web3时,这可以使我们的代码更加紧凑。 Ethers通过限制开发人员,只提供与网络互动所需的内容,来实现这种简单程度。

创建的代码大小很重要,因为它影响到你的程序的加载时间。使用Web3创建的程序的大小不是很大。但比Ethers中的相同代码要大得多。这使得它与用Ethers的相比,需要更多的时间来加载。

库的大小

Ethers的前端库明显比Web3的库小。正因为如此,当使用Ethers而不是Web3时,前端应用程序会更小。 这使得网络应用的加载速度更快,并且在浏览器中缓存依赖关系时占用的空间更少。

EthersJS的唯一目的是与Ethereum网络一起工作,并且只做这个。这就是它比web3库小的原因。web3库更大,因为它不仅仅是为Ethereum网络服务。

它还可以做更多的事情,比如说。

  • web3.bzz:它允许与一个叫做swarm的去中心化文件存储进行交互。
  • web3.shh。这用于与whisper协议进行交互,以广播信息。
  • 还有更多。

社区

Web3存在的时间比以太坊长。正因为如此,相比之下,Web3的社区更大,它使你遇到的任何挑战都比以太坊更容易找到解决方案。此外,公司更喜欢使用Web3而不是Ethers,因为它存在的时间更长。

虽然Ethers社区没有Web3社区那么大,但它有很好的文档,这使得你在任何时候感到困难时,都可以很容易地查找你不理解的东西。

部署智能合约

要在Web3中部署一个智能合约,我们要写。

const web3 = new Web3(/* your provider */);

async function main() {
    let accounts = await web3.eth.getAccounts();
    let contract = new web3.eth.Contract(abi)
                        .deploy({ data: bytecode.object })
                        .send({ from: accounts[0], gas: "1000000" });
    console.log(contract.address);
}

main();

而对于以太坊,我们可以用以下方式进行部署。

async function main() {
  const signer = new ethers.providers.Web3Provider(/* your provider */).getSigner();
  const contractFactory = new ethers.ContractFactory(abi, bytecode.object, signer);
  const contract = await contractFactory.deploy()
  console.log(contract.address);
}

main();

在Web3中发生的情况是。

  1. 我们在第一行使用我们的提供者创建一个新的web3实例。
  2. 接下来,在第二行,我们得到了所提供的账户列表。
  3. 最后,我们创建一个新的合同实例,并在第5-6行部署它。

合同是如何在Ethers中部署的。

  1. 我们创建了一个新的Web3提供者的实例,并得到了我们的账户签名者
  2. 然后,我们使用我们的abi、字节码和我们最近得到的签名者创建一个合同工厂。
  3. 然后,我们使用contractFactory.deploy()

看到这两种部署合同的方式,我们可以很容易地知道,与Web3相比,使用Ethers部署合同的代码更少。 这很好,因为我们可以很容易地知道我们的代码在做什么。我们也可以很容易地告诉这个Web3的代码是做什么的,但是,如果我们有一个更大的代码库,你会对较小的代码量感到感激。

与已部署的合约互动

这是这些库的另一个重要特征。这个功能使得开发与智能合约互动的去中心化应用程序成为可能。如果没有这一点,人们将不得不手动操作合同,这可能会导致错误。智能合约中出现的错误可能会变得非常昂贵。无论是在修复错误方面,还是在不得不支付真金白银来改变方面。

这种能力也使得在计算机上进行重度计算成为可能。这意味着数据可以在送入合约之前被处理。这就减少了在合同上的某项操作之前需要支付的气费数量。

举个例子:假设我们有一个已经部署到0x1234(地址)的智能合约,该合约有两个接口。

  • message:用于检索存储在合约中的消息。
  • setMessage:用于改变合同中的信息内容。

为了使用web3与这个部署的合同进行交互,我们写道。

const contract = new web3.eth.Contract(abi, contractAddress);
console.log(await contract.methods.message().call());
await contract.methods.setMessage("This is Chigozie").send({ from: accounts[0], gas: "1000000"});
console.log(await contract.methods.message().call());

而我们使用Ethers进行交互,比如。

const contract = new ethers.Contract(contractAddress, abi, signer);
console.log(await contract.message());
await contract.setMessage("This is Chigozie");
console.log(await contract.message());

它们都是做同样事情的片段。从我们可以看到,很容易看出Ethers版本的合同交互比Web3的代码少。

在Web3的片段中发生的事情是。

  1. 第一行,我们用ABI和合同的地址初始化合同。
  2. 接下来,我们在第3行获得已经存储在合同中的消息。
  3. 之后,我们通过发送一个事务来设置存储在合同中的消息。该事务被实例化,并通过发送方法进行签名。
  4. 最后,我们记录存储在合同消息中的消息。

而在Ethers中,我们所做的是。

  1. 我们使用部署的合同的地址、abi和签署者在第一行创建了一个新的合同实例。
  2. 然后,我们得到存储在合同中的消息。
  3. 接下来,我们使用contract.setMessage() 来改变合同的消息。
  4. 并记录存储在合同中的信息。

发送交易

这是一个在构建去中心化金融(DeFi)应用中非常方便的功能,一个人可以决定向一个地址发送一定数量的以太坊。

要使用Web3做到这一点,我们要写这样的东西。

const web3 = new Web3(/* provider */);

let receiver = /* receiver address */;
let sender = (await web3.eth.getAccounts())[0];

let receipt = await web3.eth.sendTransaction({
  to: receiver,
  value: "1000000",
  from: sender
});

而用以太坊做同样的事情,我们的代码将看起来像这样。

let receiver = /* receiver's address */;

let sender = new ethers.providers.Web3Provider(/* your provider */).getSigner();

let receipt = await sender.sendTransaction({
  to: receiver,
  value: 100000000000n
});

在Web3版本中发生的事情是。

  1. 我们在第一行使用我们的提供者创建一个新的web3实例。
  2. 第三行,我们保存了接收器的地址。
  3. 然后,我们得到我们将使用的发送者账户的地址。
  4. 最后,通过向web3.eth.sendTransaction() 方法传递一个交易对象来发送一个交易。

而对于Ethers,我们写一些稍微相关的东西。

  1. 我们得到接收者的地址。
  2. 获得对发送方地址的管理权限。
  3. 然后,发送一个交易。

总结

在这篇文章中,我们涵盖了。

  1. 什么是Web3和Ethers的JavaScript库。
  2. 我们还看到了我们如何部署和与智能合约互动。
  3. 我们学习了如何使用这两个库从一个账户向另一个账户发送以太币。
  4. 最后,我们看到了这两个库之间的一些其他重要区别。

这两个库可以做同样的事情,但流程不同。如果你想建立一个只与以太坊网络互动的应用程序,那么EthersJS库将是最受欢迎的。但是,如果你不关心空间问题,或者你的项目不仅仅需要与以太坊互动,那么你的首选应该是Web3。