以太坊實戰之《如何正確處理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。其他狀態大家可以自行驗證。
小密圈(知識星球)
個人小密圈已經建立。最近正在致力於區塊鏈各類數字貨幣節點使用相關工作,在小密圈中會持續分享實踐中遇到的各種常見的問題及解決方案、疑難雜症和各種坑。同時會回答大家一些常見的技術問題。剛剛建立,優惠加入中。希望大家多多支援。
相關文章
- 如何正確處理nonce
- 正確處理listview的positionView
- JavaScript 如何正確處理 Unicode 編碼問題!JavaScriptUnicode
- JavaScript如何正確處理Unicode編碼問題!JavaScriptUnicode
- 遇到股票套牢該如何正確處理?股票套牢解套技
- 使用 pymysql 的時候如何正確的處理轉義字元MySql字元
- 如何在Kubernetes部署期間正確處理DB模式模式
- 材質優化:如何正確處理紋理和材質的關係優化
- Recoil 中預設值的正確處理
- 處理JavaScript異常的正確姿勢JavaScript
- React.js 實戰之 事件處理ReactJS事件
- 如何正確管理HBase的連線,從原理到實戰
- Flink處理函式實戰之四:視窗處理函式
- 以太坊之Fetcher(收到BlockHash的處理)BloC
- SEO實戰:如何處理網站被黑網站
- 中國菜刀使用(實戰正確姿勢)
- Node中POST請求的正確處理方式
- 正確處理被病毒侵入電腦的方法
- Apache Flink 如何正確處理實時計算場景中的亂序資料Apache
- Flink處理函式實戰之五:CoProcessFunction(雙流處理)函式Function
- 高併發實戰之冪等處理
- 9,以正則表達處理文字(perl筆記)筆記
- Ceph的正確玩法之Ceph糾刪碼理論與實踐
- ES6 系列之非同步處理實戰非同步
- ES6系列之非同步處理實戰非同步
- CDC實戰:MySQL實時同步資料到Elasticsearch之陣列集合(array)如何處理【CDC實戰系列十二】MySqlElasticsearch陣列
- 正確理解CAP理論
- 拿到登入資料以後如何處理?
- 如何正確部署 QUICUI
- Jtti:怎樣正確處理Redis中的海量資料JttiRedis
- JavaScript 中錯誤正確處理方式,你用對了嗎?JavaScript
- MySQL 調優之如何正確使用聯合索引MySql索引
- 如何正確實現 Java 中的 HashCodeJava
- C#處理json實戰C#JSON
- 如何正確使用 Slim 框架框架
- 如何正確學習Node
- 如何正確學習JavaScript?JavaScript
- 如何正確配置 Nginx + PHPNginxPHP