以太坊实战之《如何正确处理nonce》

问题概述

以太坊系列(ETH&ETC)在发送交易有三个对应的RPC接口,分别是eth_sendTransaction、eth_sendRawTransaction和personal_sendTransaction。这三个接口发送(或构造发送内容时)都需要一个参数nonce。官方文档对此参数的解释是:整数类型,允许使用相同随机数覆盖自己发送的处于pending状态的交易。

官网解释

仅从官网的解释,我们无法获取到更多的有效的信息。但在真实生成中我们会发现如果传错nonce字段值,通过RPC接口调用发送的交易很大可能将不会被确认。如果通过console命令来操作一般不会出现此问题,因为节点已经帮我们处理了。

问题追踪

如果继续追踪问题,会发现nonce传递错误的交易可以通过eth_getTransaction查询得到相关信息,但是它的blocknumber始终未null,也就说这边交易始终未被确认。如果是在dev模式下,应该是很快就会被确认的。更进一步,通过txpool.content命令,会发现那笔交易一直处于queued队列中,而未被消费。

原因解析

为了防止交易重播,ETH(ETC)节点要求每笔交易必须有一个nonce数值。每一个账户从同一个节点发起交易时,这个nonce值从0开始计数,发送一笔nonce对应加1。当前面的nonce处理完成之后才会处理后面的nonce。注意这里的前提条件是相同的地址在相同的节点发送交易。 以下是nonce使用的几条规则: ● 当nonce太小(小于之前已经有交易使用的nonce值),交易会被直接拒绝。 ● 当nonce太大,交易会一直处于队列之中,这也就是导致我们上面描述的问题的原因; ● 当发送一个比较大的nonce值,然后补齐开始nonce到那个值之间的nonce,那么交易依旧可以被执行。 ● 当交易处于queue中时停止geth客户端,那么交易queue中的交易会被清除掉。

获取nonce值

经过上面的解释追踪,我们已经了解到了nonce的基本使用规则。那么,在实际应该用中我们如何保障nonce值的可靠性呢?这里有两个思路,第一个思路就是由业务系统维护nonce值的递增。如果交易发送就出现问题,那么该地址下一笔交易继续使用这个nonce进行发送交易。第二个思路就是使用现有的api查询当前地址已经发送交易的nonce值,然后对其加1,再发送交易。对应的API接口为:eth_getTransactionCount,此方法由两个参数,第一个参数为需要查询nonce的地址,第二个参数为block的状态:latest、earliest和pending。一般情况使用pending就可以查询获得最新已使用的nonce。其他状态大家可以自行验证。

小密圈(知识星球)

个人小密圈已经创建。最近正在致力于区块链各类数字货币节点使用相关工作,在小密圈中会持续分享实践中遇到的各种常见的问题及解决方案、疑难杂症和各种坑。同时会回答大家一些常见的技术问题。刚刚创建,优惠加入中。希望大家多多支持。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏木可大大

HTTP协议

该版本只有一个命令GET;没有HEADER等描述数据的信息; 服务器发送完毕,就关闭TCP连接。

824
来自专栏蘑菇先生的技术笔记

Redis系列(四)-低成本高可用方案设计

1787
来自专栏MessageQueue

如何在MQ中实现支持任意延迟的消息?

定时消息与延迟消息在代码配置上存在一些差异,但是最终达到的效果相同:消息在发送到 MQ 服务端后并不会立马投递,而是根据消息中的属性延迟固定时间后才投递给消费者...

1463
来自专栏JAVA高级架构

「浅入深出」MySQL 中事务的实现

关系型数据库中,事务的重要性不言而喻,只要对数据库稍有了解的人都知道事务具有 ACID 四个基本属性,而我们不知道的可能就是数据库是如何实现这四个属性的;在这篇...

3458
来自专栏后端技术探索

MySQL 数据库的高可用性分析

MySQL Replication是MySQL官方提供的主从同步方案,用于将一个MySQL实例的数据,同步到另一个实例中。Replication为保证数据安全做...

963
来自专栏丑胖侠

以太坊geth同步自动关闭问题分析

问题场景 在启动以太坊geth同步数据的过程中会出现这样的问题,就是节点同步正常,日志没有报异常信息或者报出一些底层的类异常信息,随后geth节点进程自动关闭。...

31511
来自专栏涤生的博客

长连接和心跳的那些事儿

心跳和长连接在一起介绍的原因是,心跳能够给长连接提供保活功能,能够检测长连接是否正常(这里所说的保活不能简单的理解为保证活着,具体来说应该是一旦链路死了,不可用...

783
来自专栏程序员阿凯

什么转账失败了? 那可能是「数据库事务」没有处理好

972
来自专栏技术达人

NAT穿透技术详解

传统的C/S结构是每个客户端均知道中心化的SERVER,由客户端主动与SERVER进行通信。

1554
来自专栏高爽的专栏

服务化架构下的数据一致性如何保证

在系统服务化的过程中,我们不得不面临的一个问题是多个子系统间业务数据的一致性如何保证,解决这个问题有多种方式。 XA 可能很多人首先会想到XA规范中定义的分布式...

2280

扫码关注云+社区