前言
用户事务nonce
从一个集群AB从节点试验开始。
总结
区块nonce
参考
前言
以太坊主要有两种类型nonce,一种是与矿工密切相关的块nonce,即采矿时使用;另一类用户事务与普通用户提交密切相关nonce。
用户事务nonce
- 为防止交易重播,ETH节点要求每笔交易节点nonce值。当每个账户从同一节点开始交易时,这个nonce值从0开始计数,发送笔nonce对应加1nonce处理完成之后才会处理后?的nonce。在集群环境中,不同节点共同维护同一个家庭nonce值。
- 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)
- 在集群环境下,写节点Apending因为交易会在节点B播出,nonce问题写节点Aqueued交易不会被广播。
- 在集群环境中,节点B连接到节点A(admin.addPeer(节点A)),当节点A停止时,集群将很快恢复。但是,如果节点B停止,集群将不再恢复。只有重新连接节点,才能恢复集群B。
1、发送?笔nonce给节点0的交易A,会返回交易hash,并且可以在节点Atxpool中pending看,因为播出够快,节点B也能看到。
2、再次发送nonce0交易(交易金额和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,但我们也提交到节点Bnonce交易改变提交的交易同样,我们也可以提交,但两个节点都保持相同nonce,gas price同样,交易相同不同金额的交易,它们的交易hash肯定不是,肯定不是。样品最终只会是?笔会打包,也就是哪个节点在挖掘,优先选择??pending中的交易。 (测试方法:当节点A和集群B停止节点A时,向节点B发送新的交易hash,然后快速重启节点A(保证在恢复集群之前),将同样的信息发送到节点Anonce交易,但交易价格提高,同样提交并获得新的交易hash。
5.我们提交测试queued继续发送交易nonce2(跳过1)交易到节点A,将被提交并获得交易hash,只是交易会被释放,只是交易会被释放queued中间,不会被播放到节点B。
6、再次发送nonce为2(跳过1)的交易到节点A中,提交不进去该笔交易。
7.因为节点Bqueued不会在同步节点A之前提交nonce对于2的交易,我们再次向节点提交相同的交易B,我们可以看到交易可以提交,但交易hash和节点A中相应的是?模?样的,也就是说我们依然认为是同?笔交易。
8.仍然重复操作5。我们向节点A提交笔nonce为3的交易进入节点Aqueued然后再次提交笔nonce交易3,把gas price10%仍然可以提交,但他们的hash一定不一样。
9.在我们nonce交易1后,我们观察到节点A和节点Bqueued虽然都是维护的nonce为3的交易(hash不同),但最终进?pending中会是gas price保持这两个节点的价格交易。gas price价格会加到pending中。
9、 如果我们继续提交节点Anonce为5交易进入queued中,保持gas price不变,但提交转账金额, 再次提交nonce在节点B中,两个节点分别维护了两笔交易nonce相同,但交易hash不同的交易, 但此时因为gas price?样,在补齐nonce交易4后,两个节点nonce5的交易将进入每个交易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 *Header uncles []*Header transactions Transactions // caches hash atomic.Value size 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.Time
ReceivedFrom 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博客