目录

前言

用户事务nonce

从一个集群的AB节点试验说起。

总结

区块nonce

参考


前言

以太坊中的主要有2类nonce,一类是和矿工比较密切的区块nonce,即挖矿时使用;另一类和普通使用提交提交的关系比较密切的用户事务nonce。

用户事务nonce

  1. 为了防⽌交易重播,ETH节点要求每笔交易必须有⼀个nonce数值。每⼀个账户从同⼀个节点发起交易时,这个nonce值从0开始计数,发送⼀笔nonce对应加1。当前⾯的nonce处理完成之后才会处理后⾯的nonce。集群环境下,不同节点共同维护同⼀个⽤户的nonce值。
  2. txpool中由两部分构成pending和queued组成,⼀个为待打包状态,⼀个为队列中。如果传⼊的nonce就是某⽤户下笔交易应该传⼊的nonce,那么该笔交易就会放置在pending中,等待节点打包。其次,如果传⼊的nonce值过⼤,在进⼊txpool中检查到它之前的nonce并没有使⽤过,那么此笔交易不会发送到pending中,⽽且放置在queued中。只有当前⾯的nonce补齐之后,才会进⼊到pending中。

从一个集群的AB节点试验说起。

环境
节点A:192.168.45.9
节点B:192.168.45.10
节点A和节点B集群(节点B连接到节点A)

  • 集群环境下,写⼊节点A的pending交易会⼴播到节点B中,因nonce问题写⼊节点A的queued交易,不会被⼴播。
  • 集群环境下,节点B连上节点A(admin.addPeer(节点A)),节点A停掉的情况下再次启动,会很快恢复集群,但是如果是节点B停掉的情况下,却不会再次恢复集群,只能重新连接节点,才能恢复集群B。

1、发送⼀笔nonce为0的交易给节点A,会返回交易hash,并能在节点A的txpool中pending看到,因为⼴播⾜够快,节点B中也能看到。

2、再次发送nonce为0的交易(交易⾦额和gas price等全部保持不变)给节点A,响应code=-32000,表明并没有提交成功。

3、继续测试,再次发送nonce为0的交易给节点A,并且把gas price价格提⾼(必须超过10%),
在txpool中可以看到该笔交易会把之前的交易替换掉。也就是说,针对pending⾥的交易相同nonce再次提交,并且提⾼gas price,后⾯的交易可以覆盖之前的交易。
4、如果碰到提交给节点A的pending交易,并没有及时同步到节点B,但此时同样的nonce的交易再次提交到节点B中,是可以提交进去的,但是提交的交易的hash和节点A的hash都是⼀样的(可以认为两次发送的交易就是同⼀笔交易)。

如果我们重复上⾯的情况,依然是在节点A的交易没有及时同步到节点B中,但是我们往节点B中提交同样nonce的交易,只是去改变提交的⾦额,同理我们也可以提交进去,但两个节点都维护了同样nonce,gas price相同,交易⾦额不同的交易,它们的交易hash肯定也是不⼀样的,最终只会只有⼀笔会被打包,也就是哪个节点在挖矿,优先选择⾃⼰pending中的交易。 
(测试⽅法:节点A和集群B的情况下,停掉节点A的情况下,往节点B发送⼀笔交易得到⼀个新的交易hash, 然后迅速重启节点A(保证还没来得及恢复集群的情况下),往节点A发送同样nonce的交易,但交易价格提⾼,同样提交进去并且也得到⼀个新的交易hash。

5、我们为了测试提交到queued的交易,继续发送nonce为2(跳过1)的交易到节点A中,会被提交进去,并且可以拿到交易hash,只是交易会被放⼊queued中,并且不会被⼴播到节点B。

6、再次发送nonce为2(跳过1)的交易到节点A中,提交不进去该笔交易。

7、因为节点B的queued并不会去同步节点A之前提交的nonce为2的交易,我们再次把同样的交易提交给节点B,我们可以看到该笔交易可以被提交进去,但交易hash和节点A中相应的是⼀模⼀样的,也就是说我们依然认为是同⼀笔交易。

8、依然重复操作5,我们给节点A提交⼀笔nonce为3的交易进⼊节点A的queued中,随后再次提交⼀笔nonce为3的交易,并且把gas price提⾼10%,依然可以被提交进去,但他们的hash肯定不⼀样。

9、在我们补齐nonce为1的交易后,我们观察到节点A和节点B的queued虽然都维护着nonce为3的交易(hash不同), 但最终进⼊pending中会是gas price价格⾼的交易,⾄此两个节点⼜保持⼀致。结论是gas price价格⾼的会被加⼊到pending中。

9、 如果我们继续往节点A中提交nonce为5的交易进⼊到queued中,保持gas price不变,但提⾼交转账⾦额, 
再次提交nonce为5的交易到节点B中,两个节点中⼜分别维护了两笔nonce相同,但交易hash不同的交易, 
但此时因为gas price⼀样,在补齐nonce为4的交易后,两个节点中nonce为5的交易都会进⼊到各⾃的pending中, 
但是最终只会只有⼀笔会被打包,也就是哪个节点在挖矿,优先选择⾃⼰pending中的交易。
10、 关于nonce的其它可能会碰到的问题
某⽤户的区块链维护的nonce已经到10了,但提交⼀笔交易nonce为10以下(包括10)的交易,此时会提示nonce too low,code=-32000。

某⽤户的区块链提交的交易nonce已经到10了,但依然提交⼀笔交易nonce为10的交易, 如果不改变之前交易的任何信息继续提交(两笔交易的hash是⼀样的),会提示错误,code=-32000。如果改变交易⾦额提交(交易hash不⼀样),也会提示错误,code=-32000。

总结

当nonce太小(小于之前已有交易的nonce值),交易会被直接拒绝。
当nonce太大,交易会一直处于队列之中,长久得不到执行。
当发送一个比较大的nonce值,然后补齐开始的nonce到那个nonce之间的nonce,那么交易依旧可以被执行。
当交易处于队列中时,停止geth客户端,那么交易队列中的交易会被清除。
当有一笔处于pending状态的交易,新的一笔交易与其拥有相同的nonce值,如果新交易的gas price太小,无法覆盖pending状态的交易,如果新交易的gas price高于原交易的110%,则原交易会被覆盖掉。
交易队列只保存最多64个从同一个账户发出的交易,The transaction pool queue will only hold a maximum of 64 transactions with the same From:address with nonces out of sequence. 也就是说,如果要批量转账,同一节点不要发出超过64笔交易。
当前nonce合适,但是账户余额不足时,会被以太坊拒绝;
如果发起一笔交易,但是因为gwei比较低或者网络比较忙的时候,该交易还没矿工挖出,可以通过使用相同的nonce和较高的gas费用,从而“覆盖”前一笔交易。

区块nonce

区块上的nonce是一个无意义的随机数,用于工作量证明,与挖矿的难度有关。
矿工要想成功挖出一个区块,必须不停的穷举随机数nonce,直到通过哈希算法得到的区块hash值小于或等于目标值target,目标值越低,发现随机数需要的时间越多,难度值越高。

具体的数据结构:

// Block represents an entire block in the Ethereum blockchain.
type Block struct {header       *Headeruncles       []*Headertransactions Transactions// cacheshash atomic.Valuesize atomic.Value// Td is used by package core to store the total difficulty// of the chain up to and including the block.td *big.Int// These fields are used by package eth to track// inter-peer block relay.ReceivedAt   time.TimeReceivedFrom interface{}
}// Header represents a block header in the Ethereum blockchain.
type Header struct {ParentHash  common.Hash    `json:"parentHash"       gencodec:"required"`UncleHash   common.Hash    `json:"sha3Uncles"       gencodec:"required"`Coinbase    common.Address `json:"miner"            gencodec:"required"`Root        common.Hash    `json:"stateRoot"        gencodec:"required"`TxHash      common.Hash    `json:"transactionsRoot" gencodec:"required"`ReceiptHash common.Hash    `json:"receiptsRoot"     gencodec:"required"`Bloom       Bloom          `json:"logsBloom"        gencodec:"required"`Difficulty  *big.Int       `json:"difficulty"       gencodec:"required"`Number      *big.Int       `json:"number"           gencodec:"required"`GasLimit    uint64         `json:"gasLimit"         gencodec:"required"`GasUsed     uint64         `json:"gasUsed"          gencodec:"required"`Time        *big.Int       `json:"timestamp"        gencodec:"required"`Extra       []byte         `json:"extraData"        gencodec:"required"`MixDigest   common.Hash    `json:"mixHash"          gencodec:"required"`Nonce       BlockNonce     `json:"nonce"            gencodec:"required"`
}

参考

https://wenku.baidu.com/view/c5440a5702f69e3143323968011ca300a6c3f63b.html

以太坊中的两个nonce值_Elonjelinek的博客-CSDN博客

以太坊中nonce深入解读相关推荐

  1. 以太坊中的nonce

    以太坊创建每个账户时初始nonce=0,以后每次交易nonce+1,防止以太坊中的replay attack. 参考:https://www.bilibili.com/video/BV1Vt411X7 ...

  2. 以太坊交易Nonce设置

    1 什么是nonce? 以太坊中的nonce有两个意义: 1.工作量证明:为了证明工作量的无意义的值,这是采矿的本质,这个值将决定采矿的难度, 2.账户的随机数:在一个账户中的防止多重交易的用途.例如 ...

  3. 一文讲清楚以太坊的nonce

    续上篇:一文讲清楚以太坊的gas,gasPrice,gasLimit 我们今天来讲讲以太坊的nonce.做过钱包开发的同学都应该知道,nonce是一个非常关键的参数.对于一般用户来说,各种钱包已经帮我 ...

  4. 以太坊中的账户、交易、Gas和区块Gas Limit等基本概念

    本篇文章作为科普文章,汇总整理了以太坊中的账户.交易.Gas和区块Gas Limit等相关概念,以便大家在实践中更好的与具体业务相结合. 什么是账户 以太坊账户与我们所知的账户概念有一定相似之处,却又 ...

  5. 04.区块链的那些事儿-以太坊中的 Patricia Tree

    本节主要讨论以太坊中存储的 Patricia Tree 比特币只有1棵Merkle树,而以太坊的每一个区块头,并非只包含1棵Merkle Tree,而是包含了3棵Merkle Tree,分别对应了三种 ...

  6. 以太坊中gas、gasPrice、gasLimit是什么?

    1. 什么是gas? gas是"燃料"的意思.在以太坊区块链上实现了一个EVM(以太坊虚拟机)的代码运行环境,在链上执行写入操作时,网络中的每个全节点都会进行相同的计算并存储相同的 ...

  7. [以太坊源代码分析] IV. 椭圆曲线密码学和以太坊中的椭圆曲线数字签名算法应用

    数字签名算法在Ethereum中的应用不少,目前已知至少有两处:一是在生成每个交易(Transaction, tx)对象时,对整个tx对象进行数字签名:二是在共识算法的Clique算法实现中,在针对新 ...

  8. ftl有三种映射地址_浅谈以太坊中的三种“树”

    无论是比特币还是以太坊,它们都是完全由代码创造出来的,它们的几乎所有一切都是程序执行的结果.对计算机程序有些了解的朋友应该都知道,计算机程序离不开数据结构和算法. 顺便提一下,有部分人不认为比特币和以 ...

  9. 以太坊中metamask、imtoken等钱包签名的php验证

    以太坊中metamask.imtoken等钱包签名的php验证 之前开发Dapp,需要用到以太坊钱包登陆dapp,找了很久没有这方面的库,加密算法倒是有很多,直接重新写了一个库,https://git ...

  10. 以太坊合并升级全面解读:初级篇

    目录 完成以太坊升级要执行的步骤 重要事件节点 The Merge合并关键问题 ETH 2022上海 Proto-Danksharding 已完成的准备工作 合并(Merge)后带来的重大变化 1. ...

最新文章

  1. phpstudy+phpstorm+debug
  2. 又在上海!这场人工智能大会,由图灵奖得主等带来机器学习、知识工程等干货分享!...
  3. 交叉线和直通线各自用于什么场合?为什么?_都是软电线,BVR与RV有什么不一样?...
  4. thinkphp 5.1/tp5.1 route路由bug
  5. devc 无法编译循环语句_鸡生蛋还是蛋生鸡?详解第一个编译器是怎么来的~
  6. 404 – File or directory not found.
  7. SQL基础【二十、索引】(超细致版本,前理论,后实践,应对sql面试绰绰有余)
  8. android中bmob云存储,我在将Bmob作为云进行数据存储!但不知道如何把img内的文件上传到bmob云中...
  9. Python二:【ImageEnhance】+【PIL模块】如何利用python实现图像增强
  10. 32树莓派_树莓派推出8GB内存版本
  11. linux下插入的mysql数据乱码问题及第三方工具显示乱码问题
  12. kafka监控工具Burrow安装
  13. 用python进行人脸识别
  14. ClassLoader类解析
  15. PTA程序设计基础6 7-1 列表排序、逆序 (10 分)C语言解法
  16. 如何将PDF文档转换成JPG格式
  17. 华为销售专家LTC专家许浩明老师:流程是数字化转型的基础,以华为营销LTC,华为铁三角为例
  18. 密码编码学初探——消息认证码
  19. Tableau计算同比和环比任意天数据
  20. 程序员除了去上班还能怎样赚钱?

热门文章

  1. 计算机Word更改表格中,教你修改Word文本表格
  2. 使用MybatisPlus实现ShiroRealm
  3. java实现两张图片合并起来。
  4. 如何编辑已存在的.fig文件
  5. matlab 函数最大值位置,matlab中,两个自变量的函数怎么求最大值(急急急急!!1)...
  6. excel空值排查快捷键
  7. DeepMOT: A Differentiable Framework for Training Multiple Object Trackers
  8. 果木浪子吉他入门零基础教学(70课时)
  9. pygame模块实现乌龟吃鱼游戏案例
  10. 图像处理在交通中的应用