今週のニュースレターでは、LNや他のシステムで使用されているHTLCに対する置換サイクル攻撃と、 この攻撃に対して導入された緩和策を検証し、追加の緩和策に関するいくつかの提案を掲載しています。 また、Bitcoin Core RPCに影響を与える注目すべきバグと、 Bitcoin Scriptの最小限の変更によるコベナンツの研究、OP_CAT opcode用に提案されたBIPについても掲載しています。 また、Bitcoin Stack Exchangeで人気の質問とその回答をまとめた毎月のセクションも含まれています。

ニュース

  • HTLCに対する置換サイクルの脆弱性: 先週のニュースレターで簡単に言及したように、 Antoine Riardは、すべてのLN実装に影響する脆弱性の責任ある開示を Bitcoin-DevメーリングリストおよびLightning-Devメーリングリストに投稿しました。 この開示以来、実装はこの攻撃に対する緩和策を組み込むよう更新されており、 お気に入りのLNソフトウェアを最新バージョンにアップグレードすることを強く推奨します。 影響を受けるのは支払いの転送に使用されているノードのみで、 支払いの開始と受け取りのみにチャネルを使用しているユーザーには影響はありません。

    この記事の説明を、次の3つのニュース項目にまとめました。 脆弱性の説明(本項目)、さまざまなLN実装でこれまでに展開された緩和策の説明、 メーリングリスト上で提案された追加の緩和策と解決策の概要です。

    背景として、トランザクションの置換を利用すると、 複数のインプットを持つトランザクションの1つ以上のインプットをノードのmempoolから削除することが可能です。 簡単な例を挙げると、Riardの元の説明とは若干異なりますが、 マロリーは、アウトプット AB を使用する2つのインプットを持つトランザクションをブロードキャストします。 その後マロリーは、アウトプット B のみを使用する別の単一のインプットのバージョンにトランザクションを置き換えます。 この置換後、インプット A (およびそれに含まれるすべてのデータ)は、 置換処理をしたすべてのノードのmempoolから削除されます。

    通常のウォレットがこのようなことをするのは安全ではありませんが1、 マロリーがノードのmempoolからインプットを削除したい場合には悪用できる動作です。

    特に、マロリーがボブとアウトプットの制御を共有している場合、マロリーはボブがそのアウトプットを使用するのを待ち、 ボブの支払いを追加のインプットを含む自分の支払いに置き換え、 その後その支払いを両者が共有するアウトプットを使用しない別のトランザクションに置き換えます。 これが 置換サイクル です。マイナーは、引き続きマロリーからトランザクション手数料を徴収しますが、 ボブが自分の支払いをブロードキャストした時点付近では、 ボブとマロリーどちらのアウトプットの使用も承認されない可能性が高いでしょう。

    これはLNや他のいくつかのプロトコルにとって重要です。なぜなら、 支払いを転送するユーザーが資金を失わないようにするため、 特定のトランザクションを特定の時間枠の中で発生させる必要があるからです。 たとえば、マロリーは自分のノードの1つ(マロリーA とします)を使用してボブに支払いを転送し、 ボブはその支払いを別のマロリーのノード(マロリーB)に転送します。 マロリーBは、ボブにマロリーAから転送された支払いを受け取ることができる プリイメージ を与えるか、 ボブから転送された支払いを一定時間前にキャンセル(取り消し)することになっています。 マロリーBが指定された時間まで何もしなければ、ボブはチャネルを閉じ、 転送した支払いを自分自身に払い戻すトランザクションをブロードキャストすることを余儀なくされます。 この払い戻しはすぐに承認され、ボブがマロリーAから転送された支払いをキャンセル(取り消し)できるようになります。 これにより、全員の残高が支払いを転送する前の金額に戻ります (ボブとマロリーB間のチャネルを閉じて精算するために支払われたトランザクション手数料を除いて)。

    あるいは、ボブがチャネルを閉じて転送した支払いを自分に払い戻そうとした際に、 マロリーBはボブの支払いをプリイメージを含む自分の支払いに置き換えることができます。 そのトランザクションがすぐに承認された場合は、オブはプリイメージを知り、 マロリーAから転送された支払いを請求できるようになり、ボブは満足します。

    しかし、マロリーBは、ボブの支払いをプリイメージを含む自分の支払いに置き換えた後、 すぐにそのインプットを削除した場合、ボブの支払いもマロリーBのプリイメージもブロックチェーン上に現れる可能性は低くなります。 これにより、ボブがマロリーBから資金を取り戻すのを防止します。 プリイメージがないと、トラストレスなLNプロトコルにより、ボブはマロリーAから転送された支払いを維持できなくなり、 マロリーAに返金することになります。 この時点で、マロリーBのプリイメージを含む支払いが承認され、ボブから転送された支払いを入手できるようになります。 つまり、金額 x が転送された場合は、マロリーAが支払うのはゼロ、マロリーBは x 受け取り、 ボブは x 失います(手数料は考慮してません)。

    攻撃によって利益を得るには、マロリーBはボブとチャネルを共有する必要がありますが、 マロリーAはボブへの転送パスのどこにでも存在できます。たとえば、

    マロリーA -> X -> Y -> Z -> ボブ -> マロリーB
    

    置換サイクルは、トランザクションPinning攻撃と同様の影響を及ぼします。 ただし、LNや同様のプロトコルのPinningを防止するよう設計されたv3トランザクションリレーなどの技術では、 置換サイクルを防止できません。

  • 置換サイクル用にLNノードに導入された緩和策: Antoine Riardが説明したように、 いくつかの緩和策がLN実装に導入されています。

    • 頻繁な再ブロードキャスト: リレーノードのmempoolでボブの支払いがマロリーの支払いに置き換えられ、 その後マロリーの2つめの置換によりマロリーのインプットが削除された後、 そのリレーノードはすぐに再びボブの支払いを受け入れるようになります。 ボブがしなければならないことは、自分の支払いを再ブロードキャストすることだけで、 すでに支払うつもりだったトランザクション手数料を超える費用はかかりません。

      置換サイクルが開示される前は、LN実装はトランザクションを低頻度(ブロックごとに1回以下)で再ブロードキャストするだけでした。 通常、トランザクションのブロードキャストと再ブロードキャストには プライバシーコストがかかります。 第三者がボブのオンチェーンのLN活動と彼のIPアドレスを関連付けるのが容易になる可能性があります。 ただし、現在これを隠そうとしているパブリックなLN転送ノードはほとんどありません。 現在、Core Lightning、Eclair、LDKおよびLNDはすべて、より頻繁に再ブロードキャストするようになっています。

      ボブが再ブロードキャストするたびに、マロリーは同じ手法を使ってトランザクションを再度置き換えることができます。 しかし、BIP125の置換ルールでは、マロリーは置換のたびに追加のトランザクション手数料を支払う必要があります。 これは、ボブが再ブロードキャストするたびに、攻撃が成功した場合のマロリーの収益性が低下することを意味します。

      このことは、ノードが受け入れるべきHTLCの最大額の大まかな公式を示唆しています。 攻撃者が置換サイクル毎に支払う必要のあるコストを x 、防衛者のブロック数を y 、 防衛者が平均ブロック毎に行う効果的な再ブロードキャストの回数が z である場合、 HTLCはおそらく x*y*z を少し下回る値までは合理的に安全です。

    • CLTV expiry deltaを長くする: ボブがマロリーAからHTLCを受け入れる際、 一定のブロック数(たとえば200ブロック)後に彼女がオンチェーンの払い戻しを請求できるようにすることに同意します。 ボブがマロリーBに同等のHTLCをオファーする際、 マロリーはより短いブロック数(たとえば100ブロック)後に払い戻しを許可します。 これらの有効期限の条件は、OP_CHECKLOCKTIMEVERIFY (CLTV) opcodeで記述されるため、 これらの時間の差分は CLTV expiry delta と呼ばれます。

      CLTV expiry deltaが長いほど、支払いの元の送信者は、支払いが失敗した場合に資金を回収するまでに長く待つ必要があるため、 支払人はdeltaが短いチャネルを通じて支払いをルーティングする傾向があります。 ただし、deltaが長いほど、ボブのような転送ノードがトランザクションのPinningや、 大量のチャネル閉鎖などの問題に対応する時間を確保できることも事実です。 このような利害の対立により、LNソフトウェアのdeltaのデフォルト値は頻繁に調整されてきました( ニュースレター#40#95#109#112#142#248#255参照)。

      置換サイクルの場合、CLTV deltaが長いほど、ボブはより多くの回数再ブロードキャストすることができ、 再ブロードキャストの緩和策で言及している大まかな公式に従って攻撃のコストが増加します。

      さらに、ボブの再ブロードキャストの支払いがマイナーのmempoolに入るたびに、 マイナーがそれをマイニングされるブロックテンプレートに含める可能性があり、その結果攻撃は失敗します。 マロリーが最初に行ったプリイメージへの置き換えも、マロリーがさらにそれを置き換える前にマイニングされる可能性があり、 やはり攻撃は失敗します。各サイクルの結果、これらの2つのトランザクションが マイナーのmempoolで一定時間を費やす場合、ボブによる再ブロードキャストのたびにその時間が増加します。 CLTV expiry deltaにより、その時間はさらに増加します。

      たとえば、これらのトランザクションが平均的なマイナーのmempoolでブロックあたり時間の1%しか費やさないとしても、 わずか70ブロックのCLTV expiry deltaで攻撃が失敗する可能性は50%です。 Riardのメールに記載されているさまざまなLN実装の現在のデフォルトCLTV expiry deltaの数値を使用して、 以下のプロットは、予想されるHTLCの支払いが0.1%の時間、1%の時間、 5%の時間のいずれかでマイナーのmempoolに存在するという仮定の下で、 マロリーの攻撃が失敗する(そして、置換で使用した資金を失う)確率を示しています。 参考までに、ブロック間の平均時間が600秒であるとすると、この割合は10分間に0.6秒、6秒、30秒に相当します。

      Plot of probability attack will fail within x blocks

    • mempoolのスキャン: HTLCは、ボブが払い戻しを請求する前に、 マロリーがブロックチェーンでプリイメージが承認されるようにインセンティブを与えるよう設計されています。 これはボブにとって便利です。ブロックチェーンは広く利用可能で、サイズが制限されているため、 ボブは自分に影響するプリイメージを簡単に見つけることができます。このシステムが意図したとおりに機能した場合、 ボブはLNをトラストレスに運用するために必要なすべての情報をブロックチェーンから取得できるでしょう。

      残念ながら、置換サイクルはマロリーがボブの払い戻しの請求の前に 自分のトランザクションを承認するインセンティブがなくなる可能性があることを意味します。 しかし、置換サイクルを開始するためには、マロリーはボブの支払いを置換するためにプリイメージを マイナーのmempoolに開示する必要があります。ボブがリレーのフルノードを実行している場合、 マロリーのプリイメージトランザクションはネットワークを介してボブのノードに伝播する可能性があります。 ボブがマロリーAに払い戻しを行う前にプリイメージを検出すると、攻撃は失敗し、 マロリーは攻撃のために費やした資金を失います。

      mempoolのスキャンは完璧ではありません。マロリーの置換トランザクションがボブに伝播するという保証はありません。 ただし、ボブが自分のトランザクションを再ブロードキャストする回数が増えるほど(再ブロードキャストの緩和策 参照)、 マロリーがプリイメージをボブから隠し続ける必要がある時間が長くなるほど(CLTV expiry deltaの緩和策 参照)、 プリイメージトランザクションの1つがボブのmempoolに入り、攻撃を破るのに間に合う可能性は高くなります。

      EclairとLNDは現在、転送ノードとして使用されている場合のmempoolのスキャンを実装しています。

    • 緩和策の有効性についての議論: Riardの最初の発表では、「置換サイクル攻撃は高度な攻撃者にとってはまだ実用的であると信じている」と述べています。 Matt Coralloは、「展開された緩和策ではこの問題を解決することは期待できない。 PR発言以上のものを提供するかどうかは議論の余地がある」と書いています。 Olaoluwa Osuntokunは、「私見では、これはかなり脆い攻撃で、 ノード毎のセットアップ、非常に正確なタイミングと実行、すべてのトランザクションの未承認の組み合わせ、 ネットワーク全体への即時伝搬が必要である」と主張しました

      Optechでは、この攻撃が転送ノードにのみ影響するということを再認識することが重要だと考えています。 転送ノードは、常時接続のインターネットサービスに接続されたBitcoinホットウォレットであり、 その資金がすべて盗まれるリスクが常に存在するタイプのものです。 LN転送ノードの運用のリスクプロファイルに対する置換サイクルの影響を評価する場合は、 すでに許容されているリスクの文脈でそれを考慮する必要があります。 もちろん、次のニュース項目のように、そのリスクを減らす他の方法を探す価値はあります。

  • 置換サイクルに対する追加の緩和策の提案: この記事の執筆時点で、置換サイクル攻撃の開示に応じて、Bitcoin-DevメーリングリストとLightning-Devメーリングリストに 40件を超える個別の投稿が行われています。提案された回答には以下ようなものがありました:

    • 焦土化に向かって手数料を増加する: この攻撃に関するAntoine Riardの論文と、 ZiggieMatt Morehouseによるメーリングリストへの投稿によると、 防衛者(ボブ)は、払い戻しの支払いを再ブロードキャストするだけでなく、 上流の攻撃者(マロリーA)との間で、期限が近づくにつれて手数料率がどんどん上がっていくような、 相反する代替支払いをブロードキャストし始めることが提案されています。

      BIP125のルールでは、下流の攻撃者(マロリーB)はボブの支払いを置換するたびにさらに高い手数料を支払う必要があるため、 マロリーが成功した場合に、ボブは攻撃の収益性をさらに下げることができます。 再ブロードキャストの緩和策 セクションで説明した大まかなx*y*zの式で考えてみましょう。 いくつかの再ブロードキャストで x のコストが増加すると、攻撃者に対する全体的なコストが増加し、 HTLCの最大安全値はより高くなります。

      Riardは論文の中で、特に一般的な手数料率が上昇し、攻撃者がマイナーのmempoolから彼らのトランザクションを退去させられる可能性がある期間は、 コストが対称的ではない可能性があると主張しています。またメーリングリストでは、 攻撃者が支払いのバッチ処理の形式を使って、複数の被害者に攻撃を分散させることができ、 その有効性を若干高めることができるとも述べています。

      Matt Coralloは、単なる再ブロードキャストと比較した場合のこのアプローチの大きな欠点を指摘しています。 ボブが攻撃者を破ったとしても、ボブはHTLCの金額の一部(または、場合によってはすべて)を失うことです。 理論的には、攻撃者は相互確証破壊のポリシーに従うと信じている防衛者に挑戦することはないので、 ボブは実際に高くなっていく手数料率を支払う必要はありません。 それがBitcoinネットワーク上で実際に当てはまるかどうかは証明されていません。

    • 過去のトランザクションの自動リトライ: Coralloは、「この問題の唯一の解決策は、マイナーがこれまで確認したトランザクションの履歴を保持し、 このような攻撃[…]の後にリトライすることだ」と提案しました。 Bastien Teinturierは、「Mattの意見に同意するが、L2プロトコルがこの種の攻撃に対してより強固になるためには、 Bitcoinレイヤーでより根本的な作業を行う必要がある」と応えました。 Riardも、「持続可能な修正はベースレイヤーでのみ可能で、 たとえば、確認されたすべてのトランザクションのメモリ集約的な履歴を追加するなど。」と同様のことを述べています

    • 事前署名による手数料の引き上げ: Peter Toddは、 「事前署名されたトランザクションを実行する正しい方法は、 引き上げる手数料に対する合理的なニーズをすべてカバーするのに十分な数の異なるトランザクションを事前に署名することだ。 […] B->Cトランザクションがスタックする理由はまったくない。」と主張しました。

      これは次のように機能します: ボブとマロリーBの間のHTLCの場合、 ボブは、同じプリイメージの支払いに対して手数料率が異なる10個の異なる署名をマロリーBに渡します。 署名時にマロリーBはボブにプリイメージを明かす必要はありません。 同時に、マロリーBは同じ払い戻しの支払いに対して手数料率が異なる10個の異なる署名をボブに渡します。 これは払い戻しがブロードキャストされる前に行うことができます。 使用される手数料率は(sats/vbyteで)、1、2、4、8、16、32、64、128、256、512、1024で、 当面はすべてをカバーするはずです。

      マロリーBのプリイメージの支払いが事前署名されていた場合、マロリーが可能な唯一の置換は、 ある手数料率からより高い手数料率に移行することだけです。マロリーは新しいインプットをプリイメージの支払いに追加することができず、 それができなければ、置換サイクルを始めることができません。

    • OP_EXPIRE: 別のスレッドで(ただ置換サイクルのスレッドからの引用として)、 Peter Toddは、トランザクションのスクリプトがOP_EXPIREを実行する場合、 指定されたブロック高以降にそのトランザクションを含めることを無効にするOP_EXPIRE opcodeを有効にするための いくつかのコンセンサスの変更を提案しました。 これにより、ボブの払い戻し条件が使用可能になる前にのみ、HTLCのマロリーのプリイメージ条件を使用できるようにします。 マロリーはボブの払い戻しの支払いを置き換えることができなくなり、 マロリーは置換サイクル攻撃を実行できなくなります。OP_EXPIREは、 HTLCに対する一部のトランザクションPinning攻撃にも対処することができます。

      OP_EXPIREの主な欠点は、有効にするのにコンセンサスの変更と、 ノードの帯域幅を消費するためにOP_EXPIREが使われるなどの、 特定の問題を回避するためのリレーとmempoolポリシーの変更が必要なことです。

      この提案に対する返信では、OP_EXPIREと同じ目標のいくつかを達成するために、 コンセンサスやリレーポリシーの変更を必要としない、より弱い方法が提案されました。 しかし、Peter Toddは、それでは置換サイクル攻撃を防げないと主張しました

    Optechは、このテーマに関する継続的な議論を期待し、今後のニュースレターで注目すべき進展をまとめる予定です。

  • BitcoinのUTXOセットの要約ハッシュの置き換え: Fabian Jahrは、 Bitcoin Coreの現在のUTXOセットのハッシュの計算でバグが発見されたことを Bitcoin-Devメーリングリストに投稿しました。 ハッシュは、各UTXOの高さとコインベースの情報、 つまり100ブロックのコインベースの成熟度のルールとBIP68の相対的タイムロックを適用するために必要な情報に コミットしていませんでした。これらの情報はすべて、 スクラッチで同期されたノード(現在のすべてのBitcoin Coreノード)のデータベースにまだ保存されており、 適用のためにまだ使用されているため、このバグは既知のリリース済みのソフトウェアには影響しません。 ただし、Bitcoin Coreの次期メジャーバージョンで計画されている実験的なassumeUTXO機能により、 ユーザーはUTXOデータベースを相互に共有できるようになります。 コミットメントが不完全であるということは、 変更されたデータベースが検証済みのデータベースと同じハッシュを持つ可能性があり、 assumeUTXOユーザーに対する攻撃の狭い可能性があることを意味します。

    hash_serialized_2フィールドを使用しているソフトウェアに心当たりがある場合は、 その作者にこの問題を通知し、このバグに対処するためにBitcoin Coreのメジャーバージョンで行われる変更に関する Jahrのメールを読むよう案内してください。

  • スクリプト言語の変更を最小限に抑えた一般的なコベナンツの研究: Rusty Russellは、トランザクションで実行されるスクリプトが 同じトランザクションで支払われるアウトプットスクリプトを検査できるようにするための(イントロスペクションの強力な形式)、 いくつかのシンプルな新しいopcodeを使用することについて、 彼が行った研究のリンクをBitcoin-Devメーリングリストに投稿しました。 アウトプットスクリプト(およびそれらが作成するコミットメント)のイントロスペクションを実行する能力は、 コベナンツの実装を可能にします。私たちが重要だと考えた彼の意見は次のようなものです:

    • シンプル: 3つの新しいopcodeと、 以前提案されたいくつかのコベナンツのopcode(OP_TXのような)のいずれかを使用すると、 単一のアウトプットスクリプトとそのTaprootコミットメントを完全に検査できます。 新しいopcodeはそれぞれ理解しやすく、実装も簡単に見えます。

    • かなり簡潔: Russellの例では、 妥当なイントロスペクションを実行するのに約30 vbyteを使用します(強制されるスクリプトのサイズは、このvbyteに追加されます)。

    • OP_SUCCESSの変更は有益: TapscriptBIP342仕様では、 いくつかのOP_SUCCESSx opcodeが定義されており、それらを含むスクリプトは常に成功し、 将来のソフトフォークでopcodeに条件を付けることができます(通常のopcodeのように動作するようになります)。 ただし、この動作により、任意のスクリプトの一部を含めることを許可するコベナンツで イントロスペクションを使用するのは安全ではなくなります。たとえば、 アリスは最初にVault通知トランザクションで資金を使用し、 凍結トランザクションがその資金の使用をブロックできるようにあるブロック数だけ待つ場合に、 任意のアドレスに資金を支払うコベナンツを作成したいというケースがあるかもしれません。 しかし、その任意のアドレスにOP_SUCCESSx opcodeが含まれていれば、誰でもアリスの資金を盗むことができます。 Russellはこの問題に対する2つの可能な解決策を自身の研究で提案しています。

    この研究はいくつかの議論を呼び、Russellはアウトプットの金額のイントロスペクションに関連する フォローアップの投稿に取り組んでいることを示しました。

  • OP_CAT用のBIPの提案: Ethan Heilmanは、TapscriptにOP_CAT opcodeを追加する BIPの提案をBitcoin-Devメーリングリストに投稿しました。 このopcodeは、スタックの最上位にある2つの要素を取り、それらを1つの要素に連結します。 彼は、OP_CAT自体がスクリプトに追加する機能のいくつかの説明のリンクを掲載しています。 彼が提案した参照実装は、わずか13行のコード(空白を除く)です。

    この提案は適度な議論を呼びましたが、そのほとんどは、OP_CATを有効にすることの 有用性と最悪の場合のコストに影響を与える可能性があるTapscriptの制限(および、 その制限のいずれかを変更すべきかどうか)にフォーカスしていました。

Bitcoin Stack Exchangeから選ばれたQ&A

Bitcoin Stack ExchangeはOptech Contributor達が疑問に対して答えを探しに(もしくは他のユーザーの質問に答える時間がある場合に)アクセスする、 数少ない情報ソースです。この月刊セクションでは、前回アップデート以降にされた、最も票を集めた質問・回答を紹介しています。

リリースとリリース候補

人気のBitcoinインフラストラクチャプロジェクトの新しいリリースとリリース候補。 新しいリリースにアップグレードしたり、リリース候補のテストを支援することを検討してください。

  • Bitcoin Core 25.1は、主にバグ修正を含むメンテナンスリリースです。 これは、Bitcoin Coreの現在の推奨バージョンです。

  • Bitcoin Core 24.2は、主にバグ修正を含むメンテナンスリリースです。 まだ24.0もしくは24.1を使用していて、現時点で25.1にアップグレードできない、 もしくはアップグレードしたくない人には、こちらを推奨します。

  • Bitcoin Core 26.0rc1は、主流のフルノード実装の次期メジャーバージョンのリリース候補です。 検証済みのテストバイナリは、この記事の執筆時点ではまだリリースされていませんが、 ニュースレターの公開直後に上記のURLで公開される予定です。 メジャーリリースの以前のリリース候補には、Bitcoin Core developer wikiに テストガイドと、テストに特化したBitcoin Core PR Review Clubミーティングがありました。 興味ある読者には、これらのリソースが新しいリリース候補で利用可能になっているか定期的にチェックすることをお勧めします。

注目すべきドキュメントとコードの変更

今週はニュースの量が多く、また主筆の時間的な制約もあったため、先週のコードの変更をレビューすることができませんでした。 来週のニュースレターの一部としてそれらも含める予定です。遅くなったことをお詫びいたします。

脚注

  1. ここで説明する置換サイクル攻撃は、置換される元のトランザクションよりも少ないインプットの 置換トランザクションに基づいています。これはウォレットの作成者が通常避けるように警告している動作です。 たとえば、書籍 マスタリングビットコイン第3版 には、次のように書かれています:

    同じトランザクションの複数の置換トランザクションを作成する場合は、十分に注意してください。 トランザクションの全バージョンが互いに競合していることを確認する必要があります。 すべてのトランザクションが競合していない場合、複数の別々のトランザクションが承認される可能性があり、 受信者に過剰な支払いを行う可能性があります。たとえば:

    • トランザクションバージョン0には、インプットAが含まれています。

    • トランザクションバージョン1には、インプットAとBが含まれています(たとえば、追加の手数料を支払うためにインプットBを追加する必要があったなど)

    • トランザクションバージョン2には、インプットBとCが含まれています(たとえば、 追加の手数料を支払うためにインプットCを追加する必要があったものの、Cが十分大きいためインプットAが不要になりました)。

    上記のシナリオでは、トランザクションのバージョン0を保存したマイナーは、 トランザクションのバージョン0とバージョン2の両方を承認できます。 両方のバージョンが同じ受信者に支払われると、2回支払われることになります(そして、マイナーは2つの 別のトランザクションからトランザクション手数料を受け取ることになります)。

    この問題を回避するシンプルな方法は、置換トランザクションに、以前のバージョンのトランザクションと同じインプットがすべて 必ず含まれるようにすることです。