ハードフォークで取引所の入出金をどう止めて戻すか|リプレイとreorgへの備え
約18分で読めます
約18分
目次(タップで折りたたみ)
ある暗号資産の取引所に、扱っているチェーンのハードフォークの告知が届きました。運用責任者は、入出庫をいったん止め、フォークの後に戻す計画を任されます。「新しいノードを入れて、動いたら再開すればいい」と考えたくなりますが、ここには2つの事故が潜んでいます。
- チェーンが2本に割れ、片方で出した出庫の署名が、もう片方でもそのまま通ってしまう(リプレイ)。取引所は、同じ出庫を両方のチェーンで払うことになる。
- フォークの直後は、参加者が割れたりクライアントに不具合が出たりして、チェーンの組み替え(reorg)がいつもより深くなることがある。一度残高に反映した入金のブロックが外れ、入金が消える。反映をやり直すと、二重に入金されることもある。
どちらも、ノードが動いていても起きます。だから再開は、時刻ではなく、証拠がそろったかで判断します。停止した時点の顧客台帳を記録し、分岐した後のチェーンを見分け、署名が使い回されないことと残高が合うことを確かめます。そのうえで、入庫の検知、残高への反映、出庫を分けて、段階的に戻します。
戻す順番は、後半の「再開」の章で8段階に分けて示します。大きくまとめると、次の3つです。
- 残高に反映しないまま、並行して見張る(シャドー):読み取り専用のノード・RPCから、入庫の検知まで(8段階の1〜4)
- 少額で試しに動かす(カナリア):少額の入庫の反映と、許可リスト宛ての少額の出庫を手動で承認(5〜6)
- 制限付きの自動処理を経て、通常の上限に戻す(7〜8)
以下では、この運用責任者が準備を進める順に、事前の評価から利用者への告知までを見ていきます。ノードの確認方法など、SREやチェーンエンジニアが使う細部は後半にまとめています。
この記事でわかること
- フォークの種類の見分け方と、停止した時点に残す記録
- リプレイの判定表と、入庫を残高に反映するタイミング
- 新しい資産の付与の判断、再開の条件と順番、利用者への告知
この記事で使う言葉
- ハードフォーク:古いルールでは受け入れられない、チェーンのルール変更
- リプレイ:片方のチェーンで有効な署名済みの取引が、もう片方でも実行されてしまうこと
- reorg(チェーン再編):一度つながったブロックが、別のブロックに置き換わること
- 確定(ファイナリティ):ブロックが置き換わらないとみなせる状態になること
- インデクサー:ブロックを読み取り、入出金などの出来事を社内のシステムに取り込む部品
まず確かめる:1本にまとまるアップグレードか、2本に割れるチェーン分岐か
ハードフォークは、古いルールでは受け入れられないルール変更です。その後の形は、次の2通りに分かれます。
- 計画的なアップグレード:参加者が同じソフトウェアへ移り、1つの正規のチェーンにまとまる
- チェーン分岐:複数のコミュニティ・バリデーター・マイナー・クライアントが、別々の履歴を保ち続ける
つまり、ハードフォークのたびに2つの資産が残り続けるわけではありません。この2つでは、リプレイ(署名の使い回し)と、新しい資産の付与の扱いが違います。
変更の告知を受けたら、名前だけで「通常のアップグレード」と決めつけません。出来事の記録を作り、次の点を確かめます。分からない点には、決めた扱いをします。
- 発動の条件:ブロック高・エポック・タイムスタンプ、タイムゾーン、予測の誤差。→ 分からなければ、決まった時刻だけで停止・再開を自動にしない
- リリース:クライアント名、バージョン、コミット・バイナリのダイジェスト、設定、公式リリースのURL。→ 確かめていないビルドを本番のノードに入れない
- チェーンの見分け方:ジェネシスハッシュ(最初のブロックの識別子)、network ID、chain ID、フォークのブロックのハッシュ、アドレス・資産の名前の範囲。→ 表示名やティッカーだけでRPC・ウォレットをつながない
- 分岐の可能性:古いルールを続ける参加者、代わりのクライアント、バリデーター・マイナーの支持、チェックポイント。→ 一時的な分岐と、ずっと続く分岐の両方を考えて止める
- リプレイの範囲:取引の署名、メッセージの署名、スマートコントラクトの署名ごとに、チェーン別に署名が区別されるか(署名領域の分離)。→ 出庫を再開せず、検証用の鍵と少額だけで試す
- 業務への影響:入庫、出庫、取引、ステーキング、レンディング、API、カストディの報告。→ 入出庫を止めることを、全機能を止めることと同じにしない
同じティッカーが2つのチェーンで使われていても、同じ資産・同じ送付先とは限りません。ウォレットの振り分けと残高の台帳では、フォークの出来事・チェーン・資産の組み合わせで資産を見分けます。表示名から社内のIDを逆引きしてはいけません。
手順は、時刻でなく段階で進める
「フォーク前」「フォーク後」の2つに分けるだけでは粗すぎます。証拠がそろわないまま、担当者の時刻の判断で進んでしまうからです。次の段階をはっきり決め、それぞれ次へ進むための証拠を求めます。
- 評価中:仕様、リリース、分岐の可能性、影響する機能を評価する
- 準備完了:ノードの試験運転、ウォレット・振り分けの試験、告知の準備を済ませる
- 受付停止中:新しい出庫の受付を閉じ、処理中の待ち行列を片付ける
- 記録を固定:台帳、ウォレット、ノード、未確定の取引をその時点で固定する
- 観測中:分岐の両方の候補、reorg、確定、ノードのつながり、RPCを見張る
- リプレイ試験済み:分岐ごとに、署名と送信を試す
- 少額で試行:並行監視での入庫、少額の入庫・出庫、手動承認
- 制限付きで再開:上限・許可リスト・追加の確認を付けて戻す
- 通常:通常の上限に戻し、あとで振り返る
各段階で次へ進むための証拠と、元に戻す条件は、後半の表にまとめています。
段階ごとに、責任者、承認者、とどまってよい最大の時間、戻す先を事前に決めます。チェーンの出来事の指揮者と、ノード・ウォレット・台帳・カスタマーサポートの実行担当は、別の人にします。同じ人が、観測・判定・解除を1人で終えてしまうのを防ぐためです。
フォークの前に、すべての入出庫の道筋を止められるようにする
入出庫には、アドレスの発行から資産の集約まで、いくつもの道筋があります。ウォレットの常駐プログラムのフラグを1つ切るだけでは、止まらない道筋が残ります。次のものを、1つずつ洗い出して止められるようにします。
- 入庫アドレスの発行、インデクサーの取り込み、顧客残高への反映
- 出庫の受付、承認の待ち行列、署名、送信(ブロードキャスト)
- ホットウォレットへの補充、資産の集約(sweep)
止めたときは、途中の出庫を3つに分けて扱います。「受け付けたが署名していない」「署名したが送信していない」「送信したが確定していない」です。それぞれに、どう処理し直すかの方針を持たせます。
ノードの新しいリリースは、本番と同じ設定・データ量で試験運転し、発動の前後のブロックを再実行します。チェーンごとの確かめ方は、後半の「チェーン別の確認ポイント」にまとめています。
停止した時点の記録に、何を残すか
停止した時点の記録(スナップショット)があれば、停止中の取引を1つずつ分類できます。再開の後に、入金を二重に反映したり、二重に送信したりするのを防ぐ基準になります。新しい資産を付与する計算にも使います。改ざんを検知できる目録(マニフェスト)に、次のものを保存します。
- チェーン:ブロック高・エポック、ブロックハッシュ、親ハッシュ、タイムスタンプ、chainwork(そのチェーンに積み上がった計算量)か確定済みのチェックポイント、ノードの接続先とクライアントのビルド
- 台帳:顧客・自己勘定・手数料勘定・未確定の入庫・出庫予約・ステーキングやレンディングなどの残高と、記録を取った照会の条件・版
- ウォレット:チェーンごとのアドレス、UTXOかnonce、ホット・ウォーム・コールドの残高、使っていないアドレス、集約の状態、鍵の運用ルールの版
- 処理の流れ:インデクサーの読み取り位置、最後に処理したブロックのハッシュ、出来事・ログの番号、待ち行列の位置、冪等キー(同じ処理を1回だけにするための番号)、失敗した処理の待ち行列
- 未確定の取引:社内の要求ID、生の取引データのハッシュ、nonce・入力、署名の状態、送信先、トランザクションハッシュ、置き換え・手数料の引き上げの関係
記録を取っている間も、チェーンは進みます。データベースを書き出し始めた時刻だけでは、どこが境目かあいまいです。次の3つを同じフォークの出来事に結びつけておきます。
- 顧客残高に反映した最後のブロックとハッシュ
- 出庫の受付を締め切った通し番号
- 待ち行列の位置
そうすれば、後から「どの要求が境目の内側か」を計算し直せます。秘密鍵やシード、署名用に分けた鍵そのものは、目録に出しません。
chain IDが違うだけで、安全とは判定しない
リプレイ攻撃は、一方のチェーンで有効な署名済みの取引が、送った人の意図と関係なく、もう一方でも受け入れられて実行される問題です。EthereumのEIP-155は、取引の署名にchain IDを含めます。これで、chain IDが違うチェーンのあいだのリプレイを防ぎます。ただし、分岐の両方が同じchain IDを保つ場合や、古い形式の署名が残る場合は、これだけでは防げません。そこで、見えた結果ごとに出庫の方針を決めます。
| 見えた結果 | 出庫の方針 | 理由 |
|---|---|---|
| 両チェーンで、別々の署名領域がプロトコル上必須 | 実装と接続先を確かめ、少額の試験の後に限って再開 | 正しく署名した取引は、もう一方では無効になる作り |
| chain IDは違うが、古い形式の署名・メッセージの署名・コントラクトの署名が残る | 署名の種類ごとに試し、確かめていない道筋は止める | 取引以外や古い形式に、リプレイの余地がある |
| 分岐の両方が同じchain IDを保っている | 両チェーンで受け入れ・拒否を実際に測るまで停止 | EIP-155だけでは区別できない |
| 両チェーンがUTXOを共有し、プロトコルでの保護がない | 通常のウォレットから送信しない。チェーン固有の安全な分け方を個別に設計 | 同じ署名済みの支払いが、両方で有効になりうる |
| 文書・クライアント・実測が食い違う | 安全とは判定せず、プロトコル・クライアントの担当へ上げる | 仕様の理解か実装が不完全 |
EIP-1344も、意見が割れた分岐で両チェーンが同じchain IDを保つのは安全でないと明記しています。
確かめるときは、専用の少額の鍵を使います。チェーンA向けの取引の生データと署名領域を保存し、Aでは受け入れられ、Bでは拒否されることを確かめます。逆向きも試します。ウォレットSDK、署名の仕組み、RPCの振り分け、スマートコントラクトのチェーン外の署名は、それぞれ別に判定します。
プロトコルでの保護がないチェーンで資産を切り分ける作業(coin splitting)は、いくつもの要素に左右されます。UTXOの選び方、先に通る取引、取引の相手、マイナー・バリデーターのふるまいです。一般的な記事の手順を、本番のウォレットに当てはめてはいけません。対象チェーンの公式手順、クライアントのふるまい、持っている鍵の構成をもとに、切り離した環境で設計・レビューします。
入庫は、見えたブロックをすぐ残高に反映しない
フォークの直後は、ブロックが作られ続けていても、reorgがいつもより深くなることがあります。参加者の分断や、クライアントの不具合があるからです。冒頭の2つめの事故は、ここで起きます。
入庫の処理は、少なくとも「見えた」「正規のチェーンに載った」「十分に安全・承認済み」「残高に反映した」「再編で外れた」の段階に分けます。ブロックのハッシュが正規のチェーンから外れたら、次のように扱います。
- 残高に反映する前なら、保留にする
- 反映した後なら、個別の案件にして訂正できるようにする
入庫を何承認で確定とみなすかは、チェーンの仕組みによって考え方が違います。Bitcoinの公式の支払い処理ガイドは、送信しただけでは支払いは保証されないと説明しています。ブロックに入った後も、置き換わる可能性があります。承認数が増えるほど、二重支払いのリスクは下がります(Bitcoin Payment Processing)。
一方、Ethereumのプルーフ・オブ・ステークには、safeとfinalizedというはっきりした状態があります。JSON-RPCでも参照できます(Ethereum JSON-RPC)。Ethereumの確定は、バリデーターの3分の2の投票が土台です。単純な「Nブロック経過」とは意味が違います(Ethereum Gasper)。このように、必要な承認数は、すべてのチェーンで同じ数にはなりません。
再開の条件には、平時の承認数をそのまま使いません。一時的に高めの閾値を決め、正常に戻った証拠が得られてから段階的に下げます。閾値は、次のことから決めます。
- プロトコルの安全性の前提、フォーク直後に見えたreorgの深さ
- 確定の遅れ、ノード間の食い違い
- 入庫の額、損失をどこまで許せるか
新しい資産を付与するかは、4つを別々に判断する
ずっと続く分岐で新しい資産が生まれても、「フォークのブロックの時点の残高を写せば、その日のうちに反映できる」とは限りません。少なくとも次の4つを、別々に記録します。
- 権利(entitlement):どの記録、どの残高の状態を基準にするか。借入・貸付・ステーキング・未確定の入庫・出庫予約をどう扱うか。
- 管理(control):顧客の分と自社の分を区別し、対象のチェーン上の資産を実際に安全に管理・移転できるか。
- 技術的な対応:リプレイの保護、ノード、インデクサー、ウォレットの分離、入庫アドレス、出庫、監視がそろうか。
- 業務と法令上の扱い:取り扱い、付与、金銭などでの調整、手数料、告知が、契約・法令・自主規制の上でどう扱われるか。
bitFlyerの計画されたハードフォークおよび新暗号資産への対応指針は、新しい暗号資産を付与する条件を挙げています。リプレイなど顧客の財産を侵す仕組みがないこと、顧客分と自社分のウォレットを分けられることなどです。一事業者の方針ですが、付与するかどうかを、ただの残高計算ではなく、移転の安全と分別管理に結びつけた実例です。
金融庁が公表した改正規則へのコメント回答でも、関連する論点が示されています。ハードフォークなどの前後に、決済・預入・送付を受け付けない期間を設ける可能性があるなら、その旨を利用者に説明するというものです(金融庁「コメントの概要及びコメントに対する金融庁の考え方」)。付与や取り扱いをするかは、技術チームだけでは決めません。4つ目の判定として、法務・会計の担当者の承認を別に記録します。
再開は、時間の経過ではなく、証拠一式で承認する
「24時間問題がなかった」のような時刻の条件だけでは、見張っていなかった障害を見逃します。再開を申請するときは、少なくとも次の証拠をそろえます。
- 承認したクライアントのビルドと設定。ジェネシス・chain ID、フォークのブロック、今の先頭・確定済みチェックポイントの照合結果
- 独立したノードか信頼できる情報源のあいだで、ブロックハッシュが一致していること。つながり・同期・ブロック生成・確定の状況、見えたreorg
- リプレイ試験の生の取引のハッシュ、両チェーンでの受け入れ・拒否、ウォレットSDK・署名の仕組み・コントラクト署名の結果
- 記録した時点と今のチェーン上のウォレット残高、顧客台帳、未確定の入出庫、手数料の照合の差と、承認済みの調整
- インデクサーの読み直しの結果、重複した出来事の試験、reorgからの巻き戻しの試験、待ち行列・冪等性の試験
- 少額の試行での入庫・出庫の要求ID、ブロック・トランザクションハッシュ、台帳への反映、サポート画面の表示、アラートが出るまでの端から端の結果
戻す順番は、依存の関係に合わせます。推奨する順番は次のとおりです。
- 読み取り専用のノード・RPC
- 並行監視のインデクサー
- 入庫アドレスの表示
- 入庫の検知(残高への反映は保留)
- 少額の入庫の反映
- 許可リスト宛ての少額の出庫を、手動で承認
- 制限付きの自動処理
- 通常の上限
取引の機能を続けるかどうかは、入出庫とは別に判断します。価格の形成、決済、顧客の保護から評価します。
巻き戻しのきっかけは、数値で決めておきます。深いreorg、ノード間の先頭ブロックの食い違い、確定の停止、リプレイ試験の食い違いです。二重の入金反映、署名先のチェーンの食い違い、残高の照合の差、監視の欠けも含めます。
きっかけが起きたら、新しい受付、署名、送信を止めます。すでに送信した取引は送り直さず、チェーンごとに追います。インシデントの後に機能ごとに戻す一般的な判断の枠組みは、暗号資産交換所のサービス再開設計と共通です。
利用者に何を知らせるか
JVCEAが、金融庁の第4回暗号資産制度に関するワーキング・グループに出した資料があります。会員がハードフォークなどの情報と、移転の受付停止などの制約を公表し、協会が顧客向けの案内を確かめている、と説明しています。告知は障害の後の補足ではなく、運用手順の一部です。
事前の告知には、次の8つを入れます。
- 対象の資産とネットワーク
- 止める機能
- 停止を始める予定(日本時間とUTC)
- 停止前に受け付けた入出庫の扱い
- 停止中に送金しないよう求める場合の注意
- 取引などを続けるかどうか
- 新しい資産の付与の方針(決まっていなければ、未定であること)
- 次の更新の時刻
再開のときは、「ネットワークが安定したため」だけで終わらせません。再開する機能、上限・承認数などの一時的な制限、反映が遅れている案件、問い合わせ窓口を示します。
ブロックの予測時刻は、ハッシュレートやブロック生成の状況で前後します。停止・再開の確定した時刻と、推定の時刻を区別します。予定が変わったら、同じステータスページとAPIに反映します。カスタマーサポートには社内の秘密情報を渡さず、顧客の取引がどの段階まで進んだかを説明できるようにしておきます。
実行前チェックリスト
平時の鍵の管理・ウォレットの階層・復旧の方式をまだ決めていないなら、ブロックチェーンウォレットの導入・開発と運用設計も参考にしてください。フォーク対応は、今のウォレットの守りを一時的に作り直す作業ではありません。その守りが、分岐の後も正しいチェーンに当てはまっていることを確かめる作業です。
実装する人向けの詳細
ここからは、この取引所のSREとチェーンエンジニアが使う細部です。
資産を見分ける内部ID
ウォレットの振り分けと残高台帳では、少なくともfork_event_id + chain_namespace + asset_idを使い、表示名から内部IDを逆引きしないようにします。
段階ごとの状態と、進む・戻す条件
| 状態 | 主な処理 | 次へ進むための証跡 | 戻す条件 |
|---|---|---|---|
評価中(ASSESSING) | 仕様、リリース、分岐の可能性、依存する機能を評価 | イベントの責任者、影響範囲、停止案、リプレイ試験の計画 | 仕様変更・リリースの差し替え |
準備完了(PREPARED) | ノードの試験運転、ウォレット・振り分けの試験、告知の準備 | ビルドのダイジェスト、試験結果、当番・承認者 | 同期不良・試験失敗 |
受付停止中(QUIESCING) | 新規の出庫受付を閉じ、処理中の待ち行列を収束させる | 受付停止時刻、未完了件数、残高予約 | 締め切り漏れ・二重実行 |
記録を固定(SNAPSHOTTED) | 台帳、ウォレット、ノード、未確定トランザクションを固定 | スナップショットのハッシュ、フォーク前のブロックハッシュ、高さ、照合差額 | スナップショットの不整合 |
観測中(OBSERVING) | 両方の分岐候補、reorg、ファイナリティ、ピア、RPCを監視 | 独立したノード・情報源の一致、所定の観測期間 | チェーン停止、深いreorg、クライアント間の不一致 |
リプレイ試験済み(REPLAY_TESTED) | 分岐ごとの署名・ブロードキャストの試験 | 生トランザクション、署名領域、両チェーンでの受理・拒否の結果 | 想定外に両チェーンで受理 |
少額で試行(CANARY) | 並行監視での入庫、少額の入庫・出庫、手動承認 | 台帳・インデクサー・ウォレット・エクスプローラーの照合 | 二重の入金反映、所在不明のトランザクション、監視の欠落 |
制限付きで再開(LIMITED) | 上限・許可リスト・追加確認付きで再開 | 指標、アラート、サポートの準備状況 | 巻き戻しの閾値を超過 |
通常(NORMAL) | 通常の上限へ戻し、事後に振り返る | 承認記録、未解決の個別案件の一覧、振り返りの予定 | 遅れて起きたreorg・新たな分岐 |
チェーン別の確認ポイント
EVM系ではeth_chainId、ジェネシス、フォークブロック、safe・finalizedタグ、クライアントのバージョンを、独立した複数のエンドポイントで照合します。EIP-695はeth_chainIdを、リプレイ保護されたトランザクションのchain IDを取得するRPCとして定義し、net_versionより優先するよう求めています(EIP-695)。
Bitcoin系では高さだけでなく、最良ブロックのハッシュ、ヘッダーとの差、検証の進み具合、chainwork、警告を確認します。Bitcoin Coreのgetblockchaininfoはこれらの状態を返します。getchaintipsでは、今有効なチェーン以外に知られている枝とその長さを確かめられます。特定のRPC名を全チェーンへ機械的に当てはめず、同じ意味の観測項目をクライアントごとに対応付けます。
入庫とサポート表示で使う状態名
入庫の処理は、少なくともOBSERVED、CANONICAL、SAFE/CONFIRMED、CREDITED、REORGEDを分けます。カスタマーサポートは、顧客のトランザクションがaccepted / queued / signed / broadcast / confirmed / reorgedのどこまで進んでいるかを説明できるようにします。巻き戻しのきっかけの1つはdeep_reorgとして定義します。
関連する記事
- インシデントの後の機能ごとの再開:暗号資産交換所のサービス再開設計
- 申請ごとの出庫の止め方と解除:暗号資産交換所の出庫制限設計
- 業者間の疑わしいアドレスの共有:暗号資産AMLの情報共有とトラベルルール実装
- reorgと確定の考え方を入出庫全般に広げた設計:チェーン再編・最終確定性を考慮したアプリ設計
XTELAができること
私たちは、チェーンイベントの依存関係の整理から、ノード・インデクサー・ウォレット・顧客台帳の状態設計、reorgとリプレイの試験、監視、停止と再開の運用手順書までを、PoCとして設計・開発します。貴社が扱うチェーンごとに、スナップショットに残す項目とリプレイ試験の手順を具体化し、本番のフォークの前に演習で確かめます。新しい資産の付与や利用者への説明の法的な判断は弁護士と連携して進めます。フォーク対応の準備を相談したい場合はお問い合わせください。
主要参考資料
- Ethereum Improvement Proposals: EIP-155 Simple replay attack protection
- Ethereum Improvement Proposals: EIP-1344 ChainID opcode
- Ethereum Improvement Proposals: EIP-695 eth_chainId
- ethereum.org: JSON-RPC API(2026年8月12日確認)
- ethereum.org: Gasper(2026年8月12日確認)
- Bitcoin Core RPC: getblockchaininfo
- Bitcoin Core RPC: getchaintips
- Bitcoin Developer Guide: Payment Processing
- 金融庁:コメントの概要及びコメントに対する金融庁の考え方(2020年4月3日)
- 金融庁:第4回暗号資産制度に関するワーキング・グループ 資料3(2025年10月22日、回数は2026年9月24日に議事次第で確認)
- bitFlyer:計画されたハードフォークおよび新暗号資産への対応指針(2026年8月12日確認)
資料の確認日と注意
公開された一次資料は、2026年8月12日に確認しました。ここに書いたのは、その資料にもとづく技術・業務の設計の整理です。プロトコル、クライアント、法令、事業者の方針は変わりえます。実際のフォークでは、対象チェーンの公式仕様と告知を確かめ直してください。付与や取り扱いの判断は、社内の法務・会計の担当者と確かめてください。