發(fā)送一筆以太坊網(wǎng)絡轉(zhuǎn)賬交易,除了成功之外,會遇到各種問題,比如發(fā)送的一筆交易在etherscan中查不到,或者查到是pending的狀態(tài),后來過了幾個小時消失了,這些都與節(jié)點的交易池的處理邏輯相關(guān),而交易池的邏輯可以有各種實現(xiàn),目前官方的go-ethereum 的交易池邏輯如下。
當一條交易進入挖礦節(jié)點的交易池(tx_pool)時,此節(jié)點會做出以下邏輯:
通過判斷交易hash,當這條交易已經(jīng)在節(jié)點的交易池里面時,就會丟棄掉當前收到的這一個交易。
如果是一個全新的hash,就會更具共識協(xié)議,對這一條交易做基本的驗證。驗證包括:長度,value,是否溢出當前區(qū)塊的gaslimit,Nonce值,轉(zhuǎn)賬提供的gas大小是否太小等。
如果驗證不通過就會返回相應的錯誤代碼。當驗證通過的話,需要根據(jù)當前交易池的狀態(tài)來決定,如果交易池滿了的話,那么判斷當前的轉(zhuǎn)賬交易提供的gas是否高于交易池里當前提供gas最低的那條交易。如果低了,就返回錯誤
ErrUnderpriced,這是返回的錯誤經(jīng)常在etherscan中看到。如果當前交易提供的gas值高的話,那么就剔除掉了那一條提供最低gas的轉(zhuǎn)賬交易,為當前交易騰出空間。這種情況發(fā)生之后,往往在etherscan中會觀察到正在pending的交易消失了,找不到了。(也有很大機率依然能夠查到pending的交易,原因是etherscan連接了很多節(jié)點,每個節(jié)點的交易池的狀態(tài)都是不一樣的,那條被踢出的交易在別的節(jié)點依然pending)如果當前交易的Nonce已經(jīng)在交易池里面了,說明了這個用戶想替代之前發(fā)出的相同的Nonce的交易。這時節(jié)點會判斷當前交易的gas是否高出上一條相同Nonce的交易gas某一個閾值(比如默認的是10%)。如果高出了,那么就會剔除之前的那個交易,新的交易就會保留,如果沒有高出,當前的交易就會返回失敗。
以上邏輯都通過了,那么此條交易便成功存在交易池中等待打包,當然也有可能會被別的高gas的轉(zhuǎn)賬交易剔除的概率。
總結(jié),如果你發(fā)送了一筆交易碰巧趕上了以太坊網(wǎng)絡擁堵,那么你的交易很有可能發(fā)送失敗。原因是所有的挖礦節(jié)點都不接受這么低的gas交易了,或者你本來在交易池中,被剔除了。