14

Ethers.js 非权威开发指南(下)

 3 years ago
source link: https://blog.dteam.top/posts/2021-06/ethersjs-indefinitive-guide-part2.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Ethers.js 非权威开发指南(下)

胡键 Posted at — Jun 20, 2021 阅读 80

本系列的上篇已经展示了连接钱包,调用合约和确定交易状态的全过程,对于一般的 dapp 开发已经完全足够。但对于有格调的开发者来讲,这些还不足以满足他们的胃口。那么,在下篇,你们将看到一些更加高级和特别的东西:

  • 如何处理以太坊的事件?
  • 如何监听特定合约的特定事件?
  • 如何查询以太坊的过往历史?
  • 如何获取导致交易产生的合约函数的输入参数?
  • 对于高阶合约函数(即,接受另一个合约的函数为输入值),该如何调用?
  • 如何实现签名(含 EIP712)?
  • 如何获得某个账户的公钥?

相信以上这些重口味问题的答案应该不会让各位失望。

通常,事件监听的需求来自于朴素的诉求:及时得到状态更新的通知。这种需求不仅仅局限于异步方法的调用,对于稍微复杂的一些程序,事件机制的引入也会让整个应用的架构得到简化。

Ethers.js 在 Provider 和 Contract 层面都提供了事件的支持,并且方法名称也有重叠。其中用得较多的方法如下:

  • on,对特定事件添加监听器。
  • off,移除某事件全部监听器。
  • once,添加事件监听器,并且在事件处理完成后自动移除。它和 on 的区别在于:
    • on 没有移除事件监听器这一步骤,会继续监听后续事件;
    • once 处理完当前事件之后,不再监听,对后续到来的事件不再处理;

dapp 典型的监听事件架构

虽然 Provider 和 Contract 提供了监听以太坊事件的方法,但要是不加区分到处引用这两个对象来添加事件处理函数,整个应用的代码仍不可避免地会陷入混乱。通常的做法都会结合前端框架的状态管理来做,实现上层业务代码和底层合约代码的解耦,同时又能及时得到通知。

通常做法如下:

  1. 定义状态管理涉及的业务对象,此过程类似 db 或者 domain 的设计。
  2. 在事件处理函数内,基于所监听的事件,更新对应的状态对象。
  3. 在业务代码部分订阅业务对象的更新事件,在该事件处理函数内完成页面状态更新。

对于 Angular 来讲:

  1. 状态更新部分涉及对象
Provider / Contract EventListners > Akita Service
  1. 订阅状态更新涉及对象
Akita Query > Subscribers

对于 Svelte 来讲,更简单,整个过程简化为:

Provider / Contract EventListners > Store  > Reactive 语句 / 变量

因为对 React 和 Vue 不熟,这里就此略过,但机制应该都是一样的。

使用 Provider 监听

Provider 适合粗放型事件监听,值得注意的几个事件:

  • block,新区块生成
  • error,错误发生
  • txHash 值,tx 被确认

其他事件请参见 Ethers.js 的文档。

一般来讲,你不会需要上面的第三个事件(即txHash 值),采用本系列上篇中介绍的方法要更简单一些。

block 事件在你需要一口气跟踪多个状态时最为有效,比如一次交易的变化可能导致多个地方的状态发生变化:

  • 交易对内部双边余额的变化
  • 计价合约的参数变化

本文是付费文章,剩余内容请访问以下链接支付之后继续阅读:

付费链接 (已付费:2)

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK