背景描述
以太坊钱包在一次创建多笔交易的过程中,出现了多笔pending
状态的交易,这些交易已广播到区块中,然而很长时间都未被旷工记录。另外还存在多笔已经创建的交易,未从本地节点广播出去。
使用环境
Geth 版本: 1.8.21-stable
系统版本:Centos 7.5
服务器配置:4核8G
查询交易状态:https://etherscan.io/
分析原因
通过观察分析,最早的一笔pending
状态交易设置的gasPrice
远远低于当前推荐值,然而我们并未设定固定的gasPrice
,所以这个值是由节点自己设定的。通过查阅相关资料,发现每一个地址的交易都有一个交易索引nonce
,这个索引是不断递增的,如果低索引的交易没有被确认,那么后面创建的交易也都会一直pending
,直到前面所有的交易都被旷工记录。
如何解决
找到原因后,立马修改程序,将gasPrice
设置成一个比较合适的大小(10Gwei),代码如下:
rpc.personal_sendTransaction({
"from": from_addr,
"to": to_addr,
"value": value,
"gas": "0x5208",
"gasPrice": "0x2540be400"
}, settings(:master_key))
然而,对于已经广播出去的交易,我们该怎么办呢?正因为以太坊有nonce
这个字段,所以我们可以直接新创建一笔交易,然后手动设置nonce
值,这样就可以避免创建两笔同样的交易记录。代码如下:
pending_tx = rpc.eth_getTransactionByHash(txid)
gas_price = "0x2540be400" # 这里的值至少要比之前设定的值高10%,否则无法替换
rpc.personal_sendTransaction({
"from": pending_tx[:from],
"to": pending_tx[:to],
"value": pending_tx[:value],
"nonce": pending_tx[:nonce],
"gas": "0x5208",
"gasPrice": gas_price
}, settings(:master_key))
执行这段代码之后,会生成一个新的交易ID,新交易在未被确认之前,旧的交易依然会是pending
状态,而当新交易在被确认之后,旧交易也将会消失。通过这种方式,我把低gasPrice的交易都重新替换后,所有pending状态的交易都被一一确认。
注意:对于背景描述中提到了还存在一些未广播出去的交易,重新启动geth即可自动广播。
网友评论