目錄
前言
用戶事務(wù)nonce
從一個(gè)集群的AB節(jié)點(diǎn)試驗(yàn)說(shuō)起。
總結(jié)
區(qū)塊nonce
參考
前言
以太坊中的主要有2類(lèi)nonce,一類(lèi)是和礦工比較密切的區(qū)塊nonce,即挖礦時(shí)使用;另一類(lèi)和普通使用提交提交的關(guān)系比較密切的用戶事務(wù)nonce。
用戶事務(wù)nonce
- 為了防?交易重播,ETH節(jié)點(diǎn)要求每筆交易必須有?個(gè)nonce數(shù)值。每?個(gè)賬戶從同?個(gè)節(jié)點(diǎn)發(fā)起交易時(shí),這個(gè)nonce值從0開(kāi)始計(jì)數(shù),發(fā)送?筆nonce對(duì)應(yīng)加1。當(dāng)前?的nonce處理完成之后才會(huì)處理后?的nonce。集群環(huán)境下,不同節(jié)點(diǎn)共同維護(hù)同?個(gè)?戶的nonce值。
- txpool中由兩部分構(gòu)成pending和queued組成,?個(gè)為待打包狀態(tài),?個(gè)為隊(duì)列中。如果傳?的nonce就是某?戶下筆交易應(yīng)該傳?的nonce,那么該筆交易就會(huì)放置在pending中,等待節(jié)點(diǎn)打包。其次,如果傳?的nonce值過(guò)?,在進(jìn)?txpool中檢查到它之前的nonce并沒(méi)有使?過(guò),那么此筆交易不會(huì)發(fā)送到pending中,?且放置在queued中。只有當(dāng)前?的nonce補(bǔ)齊之后,才會(huì)進(jìn)?到pending中。
從一個(gè)集群的AB節(jié)點(diǎn)試驗(yàn)說(shuō)起。
環(huán)境
節(jié)點(diǎn)A:192.168.45.9
節(jié)點(diǎn)B:192.168.45.10
節(jié)點(diǎn)A和節(jié)點(diǎn)B集群(節(jié)點(diǎn)B連接到節(jié)點(diǎn)A)
- 集群環(huán)境下,寫(xiě)?節(jié)點(diǎn)A的pending交易會(huì)?播到節(jié)點(diǎn)B中,因nonce問(wèn)題寫(xiě)?節(jié)點(diǎn)A的queued交易,不會(huì)被?播。
- 集群環(huán)境下,節(jié)點(diǎn)B連上節(jié)點(diǎn)A(admin.addPeer(節(jié)點(diǎn)A)),節(jié)點(diǎn)A停掉的情況下再次啟動(dòng),會(huì)很快恢復(fù)集群,但是如果是節(jié)點(diǎn)B停掉的情況下,卻不會(huì)再次恢復(fù)集群,只能重新連接節(jié)點(diǎn),才能恢復(fù)集群B。
1、發(fā)送?筆nonce為0的交易給節(jié)點(diǎn)A,會(huì)返回交易hash,并能在節(jié)點(diǎn)A的txpool中pending看到,因?yàn)?播?夠快,節(jié)點(diǎn)B中也能看到。
2、再次發(fā)送nonce為0的交易(交易?額和gas price等全部保持不變)給節(jié)點(diǎn)A,響應(yīng)code=-32000,表明并沒(méi)有提交成功。
3、繼續(xù)測(cè)試,再次發(fā)送nonce為0的交易給節(jié)點(diǎn)A,并且把gas price價(jià)格提?(必須超過(guò)10%),
在txpool中可以看到該筆交易會(huì)把之前的交易替換掉。也就是說(shuō),針對(duì)pending?的交易相同nonce再次提交,并且提?gas price,后?的交易可以覆蓋之前的交易。
4、如果碰到提交給節(jié)點(diǎn)A的pending交易,并沒(méi)有及時(shí)同步到節(jié)點(diǎn)B,但此時(shí)同樣的nonce的交易再次提交到節(jié)點(diǎn)B中,是可以提交進(jìn)去的,但是提交的交易的hash和節(jié)點(diǎn)A的hash都是?樣的(可以認(rèn)為兩次發(fā)送的交易就是同?筆交易)。
如果我們重復(fù)上?的情況,依然是在節(jié)點(diǎn)A的交易沒(méi)有及時(shí)同步到節(jié)點(diǎn)B中,但是我們往節(jié)點(diǎn)B中提交同樣nonce的交易,只是去改變提交的?額,同理我們也可以提交進(jìn)去,但兩個(gè)節(jié)點(diǎn)都維護(hù)了同樣nonce,gas price相同,交易?額不同的交易,它們的交易hash肯定也是不?樣的,最終只會(huì)只有?筆會(huì)被打包,也就是哪個(gè)節(jié)點(diǎn)在挖礦,優(yōu)先選擇??pending中的交易。?
(測(cè)試?法:節(jié)點(diǎn)A和集群B的情況下,停掉節(jié)點(diǎn)A的情況下,往節(jié)點(diǎn)B發(fā)送?筆交易得到?個(gè)新的交易hash,?然后迅速重啟節(jié)點(diǎn)A(保證還沒(méi)來(lái)得及恢復(fù)集群的情況下),往節(jié)點(diǎn)A發(fā)送同樣nonce的交易,但交易價(jià)格提?,同樣提交進(jìn)去并且也得到?個(gè)新的交易hash。
5、我們?yōu)榱藴y(cè)試提交到queued的交易,繼續(xù)發(fā)送nonce為2(跳過(guò)1)的交易到節(jié)點(diǎn)A中,會(huì)被提交進(jìn)去,并且可以拿到交易hash,只是交易會(huì)被放?queued中,并且不會(huì)被?播到節(jié)點(diǎn)B。
6、再次發(fā)送nonce為2(跳過(guò)1)的交易到節(jié)點(diǎn)A中,提交不進(jìn)去該筆交易。
7、因?yàn)楣?jié)點(diǎn)B的queued并不會(huì)去同步節(jié)點(diǎn)A之前提交的nonce為2的交易,我們?cè)俅伟淹瑯拥慕灰滋峤唤o節(jié)點(diǎn)B,我們可以看到該筆交易可以被提交進(jìn)去,但交易hash和節(jié)點(diǎn)A中相應(yīng)的是?模?樣的,也就是說(shuō)我們依然認(rèn)為是同?筆交易。
8、依然重復(fù)操作5,我們給節(jié)點(diǎn)A提交?筆nonce為3的交易進(jìn)?節(jié)點(diǎn)A的queued中,隨后再次提交?筆nonce為3的交易,并且把gas price提?10%,依然可以被提交進(jìn)去,但他們的hash肯定不?樣。
9、在我們補(bǔ)齊nonce為1的交易后,我們觀察到節(jié)點(diǎn)A和節(jié)點(diǎn)B的queued雖然都維護(hù)著nonce為3的交易(hash不同),?但最終進(jìn)?pending中會(huì)是gas price價(jià)格?的交易,?此兩個(gè)節(jié)點(diǎn)?保持?致。結(jié)論是gas price價(jià)格?的會(huì)被加?到pending中。
9、 如果我們繼續(xù)往節(jié)點(diǎn)A中提交nonce為5的交易進(jìn)?到queued中,保持gas price不變,但提?交轉(zhuǎn)賬?額,?
再次提交nonce為5的交易到節(jié)點(diǎn)B中,兩個(gè)節(jié)點(diǎn)中?分別維護(hù)了兩筆nonce相同,但交易hash不同的交易,?
但此時(shí)因?yàn)間as price?樣,在補(bǔ)齊nonce為4的交易后,兩個(gè)節(jié)點(diǎn)中nonce為5的交易都會(huì)進(jìn)?到各?的pending中,?
但是最終只會(huì)只有?筆會(huì)被打包,也就是哪個(gè)節(jié)點(diǎn)在挖礦,優(yōu)先選擇??pending中的交易。
10、 關(guān)于nonce的其它可能會(huì)碰到的問(wèn)題
某?戶的區(qū)塊鏈維護(hù)的nonce已經(jīng)到10了,但提交?筆交易nonce為10以下(包括10)的交易,此時(shí)會(huì)提示nonce too low,code=-32000。
某?戶的區(qū)塊鏈提交的交易nonce已經(jīng)到10了,但依然提交?筆交易nonce為10的交易,?如果不改變之前交易的任何信息繼續(xù)提交(兩筆交易的hash是?樣的),會(huì)提示錯(cuò)誤,code=-32000。如果改變交易?額提交(交易hash不?樣),也會(huì)提示錯(cuò)誤,code=-32000。
總結(jié)
當(dāng)nonce太小(小于之前已有交易的nonce值),交易會(huì)被直接拒絕。
當(dāng)nonce太大,交易會(huì)一直處于隊(duì)列之中,長(zhǎng)久得不到執(zhí)行。
當(dāng)發(fā)送一個(gè)比較大的nonce值,然后補(bǔ)齊開(kāi)始的nonce到那個(gè)nonce之間的nonce,那么交易依舊可以被執(zhí)行。
當(dāng)交易處于隊(duì)列中時(shí),停止geth客戶端,那么交易隊(duì)列中的交易會(huì)被清除。
當(dāng)有一筆處于pending狀態(tài)的交易,新的一筆交易與其擁有相同的nonce值,如果新交易的gas price太小,無(wú)法覆蓋pending狀態(tài)的交易,如果新交易的gas price高于原交易的110%,則原交易會(huì)被覆蓋掉。
交易隊(duì)列只保存最多64個(gè)從同一個(gè)賬戶發(fā)出的交易,The transaction pool queue will only hold a maximum of 64 transactions with the same From:address with nonces out of sequence. 也就是說(shuō),如果要批量轉(zhuǎn)賬,同一節(jié)點(diǎn)不要發(fā)出超過(guò)64筆交易。
當(dāng)前nonce合適,但是賬戶余額不足時(shí),會(huì)被以太坊拒絕;
如果發(fā)起一筆交易,但是因?yàn)間wei比較低或者網(wǎng)絡(luò)比較忙的時(shí)候,該交易還沒(méi)礦工挖出,可以通過(guò)使用相同的nonce和較高的gas費(fèi)用,從而“覆蓋”前一筆交易。
區(qū)塊nonce
區(qū)塊上的nonce是一個(gè)無(wú)意義的隨機(jī)數(shù),用于工作量證明,與挖礦的難度有關(guān)。
礦工要想成功挖出一個(gè)區(qū)塊,必須不停的窮舉隨機(jī)數(shù)nonce,直到通過(guò)哈希算法得到的區(qū)塊hash值小于或等于目標(biāo)值target,目標(biāo)值越低,發(fā)現(xiàn)隨機(jī)數(shù)需要的時(shí)間越多,難度值越高。
具體的數(shù)據(jù)結(jié)構(gòu):
// 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文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-495970.html
以太坊中的兩個(gè)nonce值_Elonjelinek的博客-CSDN博客文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-495970.html
到了這里,關(guān)于以太坊中nonce深入解讀的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!