老胡茶室
老胡茶室
Beta

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

胡键

上一篇起,一个关于 Ethers.js 开发的系列事实上诞生了。既然如此,我也乐得顺水推舟,干脆将其打造成一个使用 Ethers.js 开发以太坊应用的 Cookbook,以此来记录日常开发中的收获。于是乎,标题不再是上、下、续之类的麻烦字眼,直接替换成了自增数字,😄。

闲话说完,言归正传。通过本篇你可以了解到:

  • transaction 的取消或加速
  • EIP1559 对 GasPrice 的影响
  • 什么是 HD Wallet 以及它的用途
  • 对 contract 日志实现任意查询
  • contract 方法调用的权限控制

如何取消或加速 Transaction

说到取消或加速 Transaction 的原因,有人可能会列出一大堆:

  • 太慢了,希望快点结束;
  • 后悔了,想取消;
  • 市场变了,按原来的输入明显会失败,不如取消重来;
  • ……

但在我看来,最大的原因还是迟迟不能被 confirm 的 Transaction 会影响当前 Wallet 的使用,导致整个 wallet 被堵住无法使用。如果它是个人用的,影响的也就是单个人而已;但如果它是被系统使用的服务器端 wallet,那影响面可想而知。

在介绍 Transaction 的取消和交易之前,必须先了解一个基本概念:nonce。单看字面意思,dapp 开发的初学者可能会摸不着头脑。但假如把它换成另一个词 sequence,相信就好懂多了。

简单讲,nonce 的基本作用:

  • 表示当前地址已提交 transaction 的个数。它和 sequence 一样是自增的,每提交一次,个数加一。
  • 防止重放攻击,由于每次提交之后都会变化且包含在 transaction 中,这样就杜绝了过往 transaction 签名被重用的可能性。

同时,transaction 只能按顺序执行,前面的不被确认,后面的就无法被执行,就算可以不断提交,但依旧也只是进入到等待队列,对于实际的活动帮助并不大,反而还会留下一大堆未来需要处理的麻烦事。

假如你的 dapp 只有前端且由用户负责发起 transaction ,典型如 uniswap,那么作为开发者,你是不必过于关心 nonce 或 wallet 是否被堵住这类琐碎的。这并不是说使用这类 dapp 的 wallet 并不会被堵住,而是说该操心的不是你的代码,而是使用者本身。

但倘若你的 dapp 涉及到服务端且存在服务端代码需要发起 transaction 时,你的麻烦就来了。

首先,你需要有办法知道服务端的 wallet 是否被堵住。这个简单,使用下面的代码就可以办到:

const [confirmedNonce, totalNonce] = await Promise.all([
  provider.getTransactionCount(address),
  provider.getTransactionCount(address, "pending"),
]);

既然 nonce 等于当前已提交的 transaction 个数,那么使用 Ethers 的 getTransactionCount 就可以获取其值。注意示例中的 pending 参数:

  • 有它,表示将处于“待确认”的 transaction 也计入在内。
  • 否则,表示“已提交”的个数

由此,判断一个 wallet 是否被堵住的方法也就简单了:

confirmedNonce === totalNonce;

接下来,另一个需要注意的就是并发性的问题。

...
付费内容

本文是付费文章

以上是此文章的预览内容

数字产品一经出售,概不退款