如何加速处于Pending状态的以太坊交易

处于 pending 状态的交易,是矿工未打包的交易,也就是没有区块确认数的交易,只有处于此状态的交易才能被加速或者取消。一旦交易被确认,是不可逆的,就无法取消。

将 pending 状态的交易取消或者加速的原理是什么呢?
其实就是 设置相同的 nonce 和更高的 gasPrice

什么是 nonce 呢? nonce 是发送地址发送交易的数量,每次发起一笔转账,该地址的 nonce 值就会增加1。以太坊的每笔交易都会有一个 nonce 值,nonce 是连续的,不可以跳过。所以有时候一笔交易一直处于pending状态的话,会导致之后的交易也无法进行。

1. 加速交易具体操作

  • 首先获取该地址的 nonce 值,开始构建 eth 原始交易。
  • 构建原始交易的时候,要将 gasPrice 设置的足够大,比 pending 状态交易的 gsaPrice 要大,nonce 和其保持一致,转账地址和收款地址以及转账金额保持不变。
  • 然后发送交易,那么新生成的交易由于手续费更高会被矿工打包,进而确认完成。之前的交易由于 nonce 值是一样的,就会被废弃掉。因为 eth 网络规定,nonce 值是连续不可跳过,而且同一个地址每笔交易的 nonce 值不会重复的。其实就是将 pending 状态的交易给覆盖。

2. 取消交易具体操作

加速交易操作和取消交易操作的唯一的区别就在于,将转账金额修改为 0,其他都可以保持不变。

其实说是取消交易,其本质也还是加速交易,只不过转账金额变成了0,但是手续费还是会扣除。取消成功后,区块浏览器会发现多了一笔转账金额为0的交易

亲测如此: 注意对比下面两张图,第一张是被取消的交易详情,第二张是替换的交易详情。nonce值是一样的(都是8),因为我用的是中文版,所以会有点不大一样。
这是被取消的交易详情
注意:对比 gasPrice,也就是燃料价格,第二笔交易的 gasPrice 是第一笔交易gasPrice的两倍,所以很快就被矿工打包了,因此成功替换了第一笔交易。
关键在于: 手动设置相同的 nonce 和更高的 gasPrice
这是替换的交易详情


另外,关于nonce值获取的坑,做一点补充:

根据 web3j 的如下接口可以获取nonce值

BigInteger nonce = web3j.ethGetTransactionCount(fromAddress, DefaultBlockParameterName.PENDING).send().getTransactionCount();

但是这个nonce值是包含了所有pending状态的交易的,什么意思呢?举个栗子:

  • 假如我发起了一笔eth转账,由于网络拥堵或者手续费过低等原因,导致该交易一直处于pending状态;
  • 此时我没有理会这笔交易,继续发起另外一笔交易,那么结果很显然,第二笔交易由于第一笔交易没有得到确认,也会一直处于pending状态;
  • 以此类推,我无意间发起了多笔eth转账操作,结果都是处于pending状态,并且还可能伴有replacement-transaction-underpriced错误。但是这时候我不知道第一笔pending状态交易nonce值是多少,因为上面的接口获取的nonce值,包含了所有pending状态的交易,那么我该如何处理呢?
  • 当然是获取第一笔处于pending状态的nonce值啊,获取方式如下,将PENDING改成LATEST即可;
BigInteger nonce = web3j.ethGetTransactionCount(fromAddress, DefaultBlockParameterName.LATEST).send().getTransactionCount();
  • 然后再提高手续费,加速交易即可。

上面问题是我在Rinkeby测试网遇到的,记录一下:


在这里插入图片描述

关于导致 replacement-transaction-underpriced 错误,有以下原因:

  • 您的以太坊客户端中的帐户中有待处理的待处理交易;
  • 您发送的新事务与该待处理事务具有相同的nonce;
  • 您发送的新交易的天然气价格太小,无法替换待处理的交易。

以太坊 Ethereum 是由分散式节点所组成的网络架构,这些节点称为「以太坊节点 Ethereum Nodes」或「以太坊客户端 Ethereum Clients」。任何人只要有规格足够的电脑设备都能 ...