一文讲清楚以太坊的nonce

续上篇:一文讲清楚以太坊的gas,gasPrice,gasLimit

我们今天来讲讲以太坊的nonce。做过钱包开发的同学都应该知道,nonce是一个非常关键的参数。对于一般用户来说,各种钱包已经帮我们解决掉这个问题,所以不用怎么关注,但在一些特殊情况下,比如有一笔转账被pending住,但又着急转账,这个时候要是对nonce有足够的认识,就可以很轻松解决。所以,我们有必要专门讲一讲nonce。

nonce的意义

遵循上文讲gas的原则,我们追寻nonce的T-1层原理,并且追根溯源,先看看比特币中的nonce。

比特币中关于nonce的论述,在区块链领域必读书目《精通比特币》中第十章 挖矿和共识有非常详细的论述。简单来说,矿工在挖矿的过程中,为了算出符合要求的hash值(前面N个都是0, N取决于难度系数),不断地替换nonce,来做hash运算。所以,nonce主要用于挖矿。

以太坊的共识算法目前也采用POW,肯定有类似的机制。但在以太坊中,我们提及nonce,更多是说的交易的一个参数。我们看一个标准的以太坊交易参数:

一文讲清楚以太坊的nonce_第1张图片

 

nonce是一个可选参数。可以覆盖pending交易。但nonce在交易中存在意义是什么呢?一句话:防止双花,也就是防止同一地址的一笔钱被花两次。

这个结论会引出两个问题:

  1. nonce的机制如何能防止双花?
  2. 比特币交易中存在nonce吗?如何没有,它又是如何防止双花的?

nonce的机制如何能防止双花?

以太坊节点要求每笔交易必须有一个nonce数值。每一个账户从同一个节点发起交易时,这个nonce值从0开始计数,发送一笔nonce对应加1。当前面的nonce处理完成之后才会处理后面的nonce。注意这里的前提条件是相同的地址在相同的节点发送交易。

以下是nonce使用的几条规则:

● 当nonce太小(小于之前已经有交易使用的nonce值),交易会被直接拒绝。

● 当nonce太大,交易会一直处于队列之中,这也就是导致我们上面描述的问题的原因;

● 当发送一个比较大的nonce值,然后补齐开始nonce到那个值之间的nonce,那么交易依旧可以被执行。

所以,在以太坊的交易中,对于每一个地址的,是严格按照nonce往上递增的。nonce值不会重复,也不会跳跃。只有等上一笔交易成功之后,才开始下一笔,这样就能很好地防止双花问题。

 

 

比特币交易中存在nonce吗?如何没有,它又是如何防止双花的?

比特币的中不存在nonce。比特币的交易基于UTXO模型,以太坊基于Balance模型。以太坊中一个账户有多少钱,已经直接存储到世界状态肿。比特币的UTXO模型则不是这样。他是根据账本中未花费记录,一点点计算而来。具体论述可以参考《精通比特币》一书。二者不同的账户模型,决定了在处理双花的问题上,采取不同的模式。其背后的设计原理,不可不察。

 

利用nonce解决pending问题

我们明白nonce这基本原理之后,看到地址上有一笔交易因为某种原因被一直pending住,也就不会束手无策了。据我的经验,存在两种情况:

  1. 交易的gasPrice太低,遭到矿工的嫌弃,一直无法打包。
  2. 交易发起速度太快,余额依然不足,无法被打包。

解决办法很简单:把找到pending交易的nonce值,重新发起一笔交易,设定好同样的nonce就行。世面上支持这种操作的钱包不多,imToken都没有这种高级设置。幸好,我深知存在这种需求,在我亲自操刀的钱包中的高级转账设置中,可以让用户设置nonce,具体看下图:

一文讲清楚以太坊的nonce_第2张图片

 

你可能感兴趣的:(以太坊)