Ethereumの保留中トランザクションを解説:nonce、置き換え、キャンセル
Ethereumのトランザクションが待機する理由、アカウントのnonceが実行順を決める仕組み、ウォレットの高速化やキャンセル機能でできることとできないことを解説します。
このガイドの内容pendingという表示は、まだブロックに取り込まれていないことを示す
短い要約
通常の外部所有アカウントから送るEthereumトランザクションでは、nonceが連番で使われます。同じアカウントの先行nonceが消費されていない間は、後続nonceのトランザクションを実行できません。ウォレットの高速化やキャンセル機能は、通常、同じnonceを使う競合トランザクションを作成します。ブロックへの取り込みを約束するものではなく、確定したトランザクションを取り消すこともできません。
pendingという表示は、まだブロックに取り込まれていないことを示す
Ethereumのトランザクションに署名すると、ウォレットは実行クライアントやトランザクションサービスに送信できます。それを受け取ったノードはピアに中継し、ブロック提案者が後でブロックに取り込む場合があります。取り込み前は、そのトランザクションによって正規チェーンの状態は変わっていません。ウォレットやエクスプローラーの「pending」は、通常、そのサービスがトランザクションを把握しているもののブロック内ではまだ確認していないことを意味します。ネットワーク全体で共有される唯一の待機キューを指すわけではありません。Ethereum.orgのトランザクションガイドでは、署名とブロードキャストからブロックへの取り込みまでの流れを説明しています。
トランザクションが待機する理由はいくつかあります。手数料上限がブロックの条件を満たしていない、同じアカウントの先行トランザクションが未解決である、ノードがまだ受信していない、あるいはウォレットに古い情報や特定プロバイダーの情報が表示されている、といった場合です。原因ごとに確認すべきことは異なります。手数料を上げてもネットワークの選択ミスは直りません。また、最初の送金を確認せずにもう一度送ると、二重に送金する可能性があります。
「pending」は「confirmed」「finalized」「failed」とも異なります。トランザクションハッシュはreceiptが存在する前から表示されることがあります。receiptはトランザクションがブロックに取り込まれた後に確認できます。その後、Ethereumのブロックはコンセンサス上の状態を進みます。ウォレットやエクスプローラーによってラベルの使い方が違う場合があるため、短いステータス表示だけに頼らず、トランザクションハッシュ、ブロック、receipt、現在のチェーン状態を確認してください。
nonceはアカウントのトランザクション通し番号
通常のEthereum外部所有アカウント(externally owned account、EOA)には、トランザクションの順序を決めるnonceがあります。nonceはカウンターであり、手数料、タイムスタンプ、一意なトランザクションハッシュではありません。各アカウントについて、チェーンはそのアカウントの状態から見て次に期待されるnonceを使ったトランザクションだけを受け入れます。同じアカウントが同じnonceのトランザクションを正規チェーン上で2つ実行することはできません。Ethereum.orgのアカウント資料では、nonceをアカウントのトランザクションカウンターであり、リプレイ攻撃を防ぐ仕組みとして説明しています。
アカウントで次に未使用のnonceが41だとします。次の有効なトランザクションにはnonce 41を使い、それがブロックに取り込まれて適用されると、次のトランザクションにはnonce 42を使います。nonceは宛先アドレスではなく送信元アカウントに紐づきます。それぞれ独自の順序を持つため、異なる2つのアカウントが同時に番号41のトランザクションを持つことはあります。
アカウントの現在のオンチェーンnonceより大きなnonceを指定してトランザクションに署名することはできますが、実行時に順番を飛ばすことはできません。先行する未使用nonceが先に消費される必要があります。アカウントがすでに消費したnonceを使うトランザクションは古くなっており、新しいトランザクションとして実行できません。この順序により、異なるタイミングでブロードキャストされたり別々のノードに届いたりしても、ネットワークは各アカウントのトランザクションを順番に処理できます。
このnonceルールはEthereum実行レイヤー上の通常のEOAトランザクションに適用されます。あらゆるウォレット抽象化、ロールアップのシーケンサー、他のチェーンに共通する説明ではありません。スマートアカウントの仕組みでは、独自の操作やnonceのルールが追加されることがあります。詳しくは後の節で説明します。
pendingとqueuedはトランザクションプールのローカルなラベル
Ethereumには、すべてのウォレット、ノード、ブロックエクスプローラー、提案者がまったく同じ内容を見る、単一で同期された待機場所はありません。各実行クライアントは、受信したトランザクションのうち独自の制限やポリシーに照らして対象と判断したものをローカルのトランザクションプールに保持します。あるノードのプールには存在し、別のノードには存在しないトランザクションもあります。Gethのtxpool RPCドキュメントでは、そのクライアントにおけるローカルのpendingとqueuedのグループを確認でき、同じ送信者とnonceに複数のトランザクションが関連づけられる場合があることも説明しています。
Gethの用語では、pendingは一般に、現在のアカウント状態からnonce順に処理できるトランザクションを指します。queuedには、先行nonceの空きを待つ将来のnonceのトランザクションが含まれることがあります。これはクライアントのインターフェース上の名称であり、すべてのEthereumソフトウェアが表示する必要のあるコンセンサス上の状態ではありません。ウォレットは未確定の一覧すべてを「pending」と呼ぶ一方、エクスプローラーは自社のデータプロバイダーが確認したトランザクションだけを表示することがあります。
たとえば、あるノードがnonce 41のトランザクションとnonce 43のトランザクションを把握していても、42より先に43を実行することはできません。42が届くか、別の方法でアカウントのnonceが進むまで、43をキューに置く場合があります。43を受け取っていない別のノードには、そのトランザクションはまったく表示されません。このため、2つのエクスプローラーがトランザクションをpendingと表示するか見つからないと表示するかで食い違っても、どちらの画面もすべてのバリデーターが何を見たかを証明するものではありません。
クライアントによっては、同じ送信者とnonceに対して未確定の候補を複数保持できます。これらは同じ順序枠を取り合う代替候補であり、両方が順番に適用されるわけではありません。プールの容量、トランザクションの保持期間、置き換えのルールは実装ごとのポリシーであり、ソフトウェアのバージョンによって変わることがあります。たとえばGethでは、設定可能なトランザクションプールのオプションに、クライアント固有の価格引き上げ幅が含まれています。これはEthereum全体に共通する手数料ルールではありません。対象となるオプションについてはGethのコマンドラインリファレンスを確認してください。
未解決のnonceが後続トランザクションを止めることがある
アカウントの次のオンチェーンnonceが41だとします。nonce 41のトランザクションAをブロードキャストし、その後nonce 42のトランザクションBを送信します。Aが未解決のままなら、Bを先に適用することはできません。Bはローカルキューに置かれたり、ウォレットにだけpendingと表示されたり、まだ受信していないエクスプローラーには表示されなかったりします。重要なのはnonceの順序関係であり、ウォレットが2つのトランザクションを作成したり表示したりした順番ではありません。
Aが最終的にブロックに取り込まれると、アカウントのnonceは42に進み、Bは自身の有効性、手数料条件、プールのポリシーを満たせば処理対象になります。Aがnonce 41を使う別の有効なトランザクションに置き換えられ、そのトランザクションが取り込まれた場合、置き換えたトランザクションが同じ順序枠を占めます。アカウントの別のトランザクションがnonce 41を消費した場合、古いnonce 41の候補は無効になり、後から実行できません。
そのため、より大きなnonceで新しいトランザクションを送ることは、詰まったトランザクションを解消する一般的な方法ではありません。順序の空きの後ろに別のトランザクションを追加するだけです。Bのほうが後のnonceなら、BをキャンセルしてもAは解決しません。変更を加える前に、アカウントで最も早い未解決nonceから状態を確認してください。
nonceの空きは一時的な場合もあれば、長引く場合もあります。先行トランザクションが確認中のノードに届いていない、手数料設定が現在の状況で魅力的でないか不十分、あるいはあるノードのプールから削除済み、といった可能性があります。別の端末で作成したqueuedトランザクションがウォレットに表示されている場合もあります。画面だけではどれが起きたか分からないため、確定済みのアカウントnonce、トランザクションハッシュ、複数の信頼できる情報源を比較してください。

手数料の設定はブロックへの取り込みに影響するがnonce順は変えない
nonce順と手数料の適格性は別々の制約です。次に正しいnonceを持つトランザクションでも、手数料パラメーターがブロックの条件を満たさなければ待機する場合があります。より大きなnonceのトランザクションがチップを上げても、先行トランザクションを飛び越えることはできません。nonce 42の手数料を上げても、nonce 41は消えません。
標準的なEIP-1559トランザクションでは、最大手数料が取り込まれるブロックのbase feeをカバーできる必要があり、priority feeはブロック提案者の選択に影響することがあります。トランザクションの待機中にbase feeもブロックの空き容量も変化します。最大手数料は上限であり、上限を高くしても特定の確認時間は保証されません。Ethereumのgas手数料ガイドでは、各項目と実効手数料の決まり方を説明しています。
ノードやウォレットは、追加の中継ルールや置き換えルールを適用することがあります。これらのポリシーは、そのサービスが受け入れたり転送したりするものを決めますが、すべてがコンセンサスルールというわけではありません。たとえばGethでは、自身のプールにあるpendingトランザクションを置き換える価格引き上げのしきい値を設定できます。他のクライアント、プロバイダー、ウォレット、ソフトウェアバージョンでは動作が異なる可能性があります。覚えている割合や一定の待ち時間を、ネットワーク全体の保証として当てにしないでください。
より低いnonceが未解決のためにトランザクションが待機しているなら、まずそのnonceを持つトランザクションを特定します。base feeの現在の条件を手数料上限が満たせないために待っているなら、変更する前に手数料項目を理解してください。手数料計算にはEthereumの手数料ガイドが役立ちます。この記事は、それとは別の順序の問題を扱います。
高速化は同じnonceの置き換え候補を送信する
ウォレットの「高速化」機能は一般に、同じアカウントから同じnonceを使い、手数料パラメーターを調整した新しいトランザクションを作成します。アカウントはそのnonceについて1つのトランザクションしか実行できないため、2つの候補は競合します。置き換えが関係するトランザクションプールに受け入れられてブロックに取り込まれると、そのnonce枠を占めることができ、元のトランザクションは正規チェーン上で実行できなくなります。MetaMaskのpendingトランザクションに関する案内では、同じnonceを使い手数料を上げて再送する機能として説明されています。
置き換え後も元の宛先や処理内容を保ち、手数料項目だけが変わる場合がありますが、そう決めつけず署名画面を確認してください。ウォレットによっては、ほかの項目を表示したり、機能の名称が異なったりする可能性があります。置き換えに署名する前に、送信元アカウント、nonce、宛先、値、コントラクトデータを確認します。置き換えによってトランザクションの動作が変わるなら、単なる無害な手数料調整ではありません。
置き換えがすべての場所で受け入れられることや、すぐにブロックへ入ることは保証されません。元のトランザクションはすでに取り込まれているかもしれません。ノードが自身のポリシーで置き換えを拒否したり、提案者にとってなお魅力が足りなかったり、監視しているノードへサービスが中継しなかったりすることもあります。元のトランザクションがすでに確定している場合、消費済みnonceで別のトランザクションを送っても取り消せず、通常は古いトランザクションとして拒否されます。
ここでいう「置き換え」は、同じアカウントから同じnonceを使う競合トランザクションを意味します。BitcoinのRBFやCPFPの手順をEthereumに持ち込まないでください。Bitcoinは異なるトランザクションモデルを使い、手数料を引き上げる仕組みもEthereumアカウント向けの手順ではありません。
キャンセルは同じnonce枠を取ろうとする試み
署名済みのEthereumトランザクションがブロードキャストされた後、すべてのノードからそれを取り下げるプロトコルレベルの取り消しコマンドはありません。一部のウォレットでは、未確定の間にキャンセルを試せます。通常は同じアカウントから同じnonceを使う別のトランザクションの公開を試みます。よくあるウォレットの方法の一つは、自分のアドレス宛てに価値0のトランザクションを送ることです。キャンセル候補が元のトランザクションより先に受け入れられて取り込まれると、nonceを消費して元の候補が後から実行できない状態になります。具体的な構成や利用可否はウォレットによります。
元のトランザクションとキャンセル候補は競争します。元のほうが先に取り込まれた場合、後から送ったキャンセルで影響を取り消すことはできません。どちらも受け入れられず取り込まれなければ、nonceは未解決のままになる場合があります。ウォレットのボタンを押したことや成功通知だけでは、キャンセルが勝った証明になりません。生成されたトランザクションハッシュと正規チェーン上の状態を確認してください。MetaMaskの案内では、キャンセルの試行はまだpendingのトランザクションに限られ、確定済みのトランザクションはキャンセルできないと明記されています。
キャンセルトランザクションに署名する前に、置き換えたいトランザクションと同じアカウント・nonceを使っていることを確認し、ウォレットに表示されるすべての項目を確認してください。取り込まれた場合は、別途ネットワーク手数料が必要になることがあります。キャンセル候補自体が待機したり、該当するトランザクションプールのポリシーによって元のトランザクションの置き換えに失敗したりする可能性もあります。ウォレットの「キャンセル済み」という表示はプロトコル上で取り消された証拠ではありません。どのトランザクションがnonceを消費したか確認してから結果を判断してください。
トランザクションがすでにトークン承認、コントラクト呼び出し、送金を実行している場合、後続トランザクションのキャンセルで完了済みの状態変更を元に戻すことはできません。一部のコントラクト操作には別の後続手段がありますが、利用可否と影響はコントラクトによります。画面にキャンセルと表示されているというだけで、内容の分からないトランザクションに署名しないでください。
included、reverted、dropped、missingはそれぞれ異なる観測結果
ブロックに取り込まれたトランザクションにはブロックとreceiptがあります。成功すれば、意図した状態変更が適用されている可能性があります。EVM実行がrevertした場合、その実行による状態変更はロールバックされますが、トランザクションはアカウントのnonceを消費し、gasを請求されることがあります。ウォレットの通知から成功を推測せず、receiptと実行ステータスを確認してください。取り込みと実行結果の違いについては、Ethereumのトランザクションガイドとgasガイドを参照してください。
「dropped」や「not found」という表示は、単一のウォレット、エクスプローラー、RPCプロバイダー、またはローカルプールの報告であることがよくあります。それだけではプロトコルがトランザクションをキャンセルしたとも、nonceが空いたとも証明できません。別のノードがまだ把握しているかもしれませんし、ウォレットが署名済みトランザクションを再送する場合や、後のブロックでアカウントのnonceがすでに進んでいたと分かる場合もあります。逆に、確認した画面には古いトランザクションがなくても、アカウントの確定済みnonceは変わっていないことがあります。
トランザクションハッシュが見つからない場合は、作成時と同じチェーンとアカウントを選択しているか確認してください。アカウントの最新オンチェーンnonceとトランザクションのnonceを比較し、その送信元の最近のトランザクションを調べます。nonce too lowという応答は、エンドポイントの視点ではnonceがすでに消費された可能性を示す手がかりです。同じ要求を繰り返す理由にはなりません。どのトランザクションがnonceを使ったか、ブロックが正規のままかを確認してください。
取り込まれたトランザクションでも、チェーンが安定する前の短期間の再編成の影響を受けることがあります。ウォレットやエクスプローラーは表示が変わるとラベルを更新する場合があります。重要な送金では、受取サービスの確認ポリシーに従って待ち、必要に応じてより強いコンセンサスファイナリティを確認してください。「1つのブロックで見えた」と「どんな状況でも不可逆」は同じ意味ではありません。
対処する前に最も早い未解決nonceを確認する
まずチェーン、送信元アカウント、トランザクションハッシュを確認します。正しいネットワークの信頼できるエクスプローラーでハッシュを検索してください。receiptの有無、使用nonce、実行の成否、アカウントが後続トランザクションを送ったかを確認します。トランザクションの確認にシードフレーズを公開したり入力したりする必要はありません。公開チェーンの検索には公開アドレスとトランザクションハッシュで十分です。
ハッシュが表示されない場合、アカウントの最新確定nonceとウォレットに表示されたnonceを比べます。開発者やノード運用者は、ブロックタグlatestとpendingを使ってeth_getTransactionCountを照会できます。Ethereum.orgのJSON-RPCリファレンスでは、latestは最新ブロックの状態、pendingはpending状態を指すと定義されています。ただしpendingの結果は、そのRPCエンドポイントの見え方に左右され、プロバイダーごとに異なる値を返すことがあります。多くの利用者はコマンドを実行しなくても、ウォレットのアカウント履歴と信頼できるエクスプローラーから同じ初期情報を得られます。
次に、まだ消費されていないnonceのうち最も小さいものから確認します。元のトランザクションがまだ表示され、ウォレットが置き換えに対応しているなら、署名する前に置き換えの正確な項目と手数料設定を確認してください。表示されない場合は、ネットワークから消えたと決めつけず、ウォレットやRPCプロバイダーに再送と置き換えの扱いを確認します。nonceがすでに消費されているなら、ほかの操作をする前に取り込まれたトランザクションを特定します。より大きいnonceで新しいトランザクションを何度も送るのは避けてください。最初の空きを解消できないままキューを長くする可能性があります。
ここまでの手順は、標準的なEthereum外部所有アカウントのトランザクションを対象にしています。アカウント抽象化の仕組みではbundler経由でUserOperationを送信でき、スマートアカウントでは単一のカウンターより複雑なnonceキーやシーケンスを使う場合があります。EIP-4337はその操作向けのnonce構造を定義しているため、アカウント抽象化を使うウォレットは、この記事のEOAの例と同じようには動かないことがあります。送金先ネットワーク、アドレス、送金状況については暗号資産送金チェックリストも確認してください。
よくある質問
Q1Ethereumのトランザクションは確定後にキャンセルできますか?
できません。ウォレットは未確定の間に同じnonceの置き換えを試みられますが、すでにブロックに取り込まれて実行されたトランザクションを取り消すことはできません。操作する前にトランザクションハッシュとチェーン上の状態を確認してください。
Q2次のEthereumトランザクションも待機しているのはなぜですか?
通常のEOAトランザクションはnonce順に実行されます。先行nonceが未解決なら、後続nonceは先に実行できません。ウォレットに表示されていたり、より高い手数料を提示していたりしても同じです。
Q3「dropped」はトランザクションがキャンセルされたという意味ですか?
必ずしもそうではありません。ウォレット、エクスプローラー、ノードの一つがトランザクションを見失っただけかもしれません。そのnonceを空きと見なす前に、正しいネットワークでトランザクションハッシュとアカウントの最新nonceを確認してください。
出典
問題を報告
この記事のリンクを含むメールを準備します。送信すると Mark に報告が届きます
クイックチェック
記事を読み終えたら、3問で確認しましょう
問題 01
あるアカウントにnonce 41の未解決トランザクションとnonce 42のトランザクションがあります。後者にできることは何ですか?
答えを選ぶと解説を確認できます