本系列的上篇已经展示了连接钱包,调用合约和确定交易状态的全过程,对于一般的 dapp 开发已经完全足够。但对于有格调的开发者来讲,这些还不足以满足他们的胃口。那么,在下篇,你们将看到一些更加高级和特别的东西:
- 如何处理以太坊的事件?
- 如何监听特定合约的特定事件?
- 如何查询以太坊的过往历史?
- 如何获取导致交易产生的合约函数的输入参数?
- 对于高阶合约函数(即,接受另一个合约的函数为输入值),该如何调用?
- 如何实现签名(含 EIP712)?
- 如何获得某个账户的公钥?
相信以上这些重口味问题的答案应该不会让各位失望。
监听事件
通常,事件监听的需求来自于朴素的诉求:及时得到状态更新的通知。这种需求不仅仅局限于异步方法的调用,对于稍微复杂的一些程序,事件机制的引入也会让整个应用的架构得到简化。
Ethers.js 在 Provider 和 Contract 层面都提供了事件的支持,并且方法名称也有重叠。其中用得较多的方法如下:
on
,对特定事件添加监听器。off
,移除某事件全部监听器。once
,添加事件监听器,并且在事件处理完成后自动移除。它和on
的区别在于:on
没有移除事件监听器这一步骤,会继续监听后续事件;once
处理完当前事件之后,不再监听,对后续到来的事件不再处理;
dapp 典型的监听事件架构
虽然 Provider 和 Contract 提供了监听以太坊事件的方法,但要是不加区分到处引用这两个对象来添加事件处理函数,整个应用的代码仍不可避免地会陷入混乱。通常的做法都会结合前端框架的状态管理来做,实现上层业务代码和底层合约代码的解耦,同时又能及时得到通知。
通常做法如下:
- 定义状态管理涉及的业务对象,此过程类似 db 或者 domain 的设计。
- 在事件处理函数内,基于所监听的事件,更新对应的状态对象。
- 在业务代码部分订阅业务对象的更新事件,在该事件处理函数内完成页面状态更新。
对于 Angular 来讲:
- 状态更新部分涉及对象
Provider / Contract EventListners > Akita Service
- 订阅状态更新涉及对象
Akita Query > Subscribers
...
付费内容
本文是付费文章
以上是此文章的预览内容
数字产品一经出售,概不退款