3MIKAN
仮想通貨

nonce too low・replacement underpricedの原因と直し方

nonce too lowとreplacement transaction underpricedの違いを、latest・pending nonce、speed up、cancel、同一nonce置換から解説します。

latest nonceとpending nonceを比較し同一nonceの置換トランザクションを判定する図

nonceは、同じアカウントから送るトランザクションの実行順を決める連番です。nonce too lowreplacement transaction underpricedは似ていますが、確認すべき状態が違います。

latest nonce、pending nonce、送信nonceから確定・保留・置換候補を判定する図

先にlatestとpendingを取得する

const [latestNonce, pendingNonce] = await Promise.all([
  publicClient.getTransactionCount({
    address,
    blockTag: 'latest',
  }),
  publicClient.getTransactionCount({
    address,
    blockTag: 'pending',
  }),
])
  • latest: 確定済みblockを基準にした次のnonce
  • pending: ノードが認識するpendingトランザクションも考慮した値

RPCごとにmempoolの見え方が違う場合があるため、pending値は絶対的なネットワーク全体の証明ではありません。Explorer、wallet、別RPCのhash・from・nonceも照合します。

nonce too low

送信しようとしたnonceが、そのノードから見てすでに消費済みの場合に発生します。

確認順は次の通りです。

  1. 同じfrom・chainでlatest nonceを取得
  2. 送信requestのnonceと比較
  3. そのnonceを使って確定した別hashを探す
  4. walletのローカル履歴だけを消す前にExplorerを確認

元トランザクションが別hashへ置換されて確定していると、古い署名済みraw transactionを再送してもnonce too lowになります。

replacement transaction underpriced

同じnonceのpendingトランザクションを置換しようとしたが、新しいfeeがノードの置換条件を満たさないときに使われる代表的なエラーです。必要な上昇幅はクライアント、RPC、ネットワーク条件で変わるため、固定の割合をプロトコル保証として扱わないでください。

重要なのは次の2点です。

  • 元トランザクションと同じnonceを使う
  • 新しいfee条件を十分に高くする

EIP-1559形式ではmaxFeePerGasmaxPriorityFeePerGasの両方を確認します。古いgas priceだけを見ていると、置換条件を満たさないことがあります。

speed upとcancelはどちらも置換

MetaMaskのspeed upは、同じ内容・同じnonceをより高いfeeで再送する操作です。cancelは、同じnonceで自分宛て0 ETHなどの別トランザクションを先に確定させる試みです。

どちらも元トランザクションがまだpendingである間だけ試せます。すでに確定したトランザクションは取り消せません。また、置換トランザクションが先に取り込まれる保証もないため、操作後はhashとreceiptを確認します。

droppedとreplacedを断定する前に

あるRPCでhashが見えなくなっただけでは、ネットワーク全体からdroppedしたと断定できません。次を記録します。

chainId
from
original hash / nonce / fee
replacement hash / nonce / fee
latest nonce
pending nonce
各hashのreceipt
確認RPCと日時

同じnonceの別hashが確定していればreplacedと判断できます。どのhashにもreceiptがなく、複数RPCでも長時間見えず、nonceが未消費ならdropped候補です。

送金未反映を調べている場合はMetaMaskの送金確認、receipt・calldataまで見る場合はviemで失敗トランザクションを解析するへ進んでください。gas見積もりの失敗はestimateGasの記事へ分離します。

確認した一次情報