スマートコントラクトの本番監視と事故対応|警報の基準・初動・再開の判断

コラム

/約19分で読めます

コラム

/約19分

スマートコントラクトの本番監視と事故対応|警報の基準・初動・再開の判断
目次(タップで折りたたみ)

    監査が終わり、スマートコントラクトをいよいよ本番に出す。その直前に、開発責任者はこう聞かれます。「本番で何か起きたら、誰が気づいて、誰が止めるのか」。

    Euler Financeが2023年に受けた攻撃の記録では、最初の攻撃用コントラクトが置かれてから資金が流れ出るまで、秒単位で進みました。その後は、同じ手口をまねる攻撃、資金の追跡、連絡・交渉が同時に走っています。気づいてから人が集まって相談していては、間に合わないおそれがあります。ですから、誰が気づき、誰が止めるかは、公開の前に決めておく必要があります。

    監査が見るのは、リリース時点のコードです。本番では、価格、流動性、外部のプロトコル、管理鍵、フロントエンドの状態が変わり続けます。ノードとの通信(RPC)や、定期処理を動かすボット(キーパー)も同じです。そのため、監査を通したコードでも、それだけでは安心できません。Ethereum.orgも監査を万能とはせず、公開後の守りとしてイベントの監視と緊急停止を挙げています。

    では、何を用意すればよいのか。警報の基準額のような設定値は、預かり資産の規模や流動性によって意味が変わります。他社の値をまねても、自社に合うとは限りません。そこで自社で「絶対に崩れてはいけない条件」と「損失が広がる速さ」を決め、そこから警報・当番・停止・再開の決まりを作ります。そして、見逃す、通知が届かない、鍵が使えない、誤って止める、といった失敗も含めて手順を試しておきます。以下では、開発・運用・セキュリティの担当と事業責任者が、この順に何を決めるかを見ていきます。

    この記事でわかること

    • 何を監視し、警報の基準をどう決めるか
    • 緊急停止の権限の分け方と、事故が起きたときの手順
    • 再開してよい条件と、本番に出す前の受け入れ基準

    この記事で使う言葉

    • 不変条件:どんなときも成り立っていなければならない条件。例:預かり資産が負債を下回らない
    • 封じ込め:被害が広がらないよう、機能を止めたり上限を下げたりすること
    • ガーディアン:緊急時に停止だけを実行できる担当・アカウント
    • チェーン再編:いったん確定したように見えたブロックが、別のブロックに置き換わること
    • フォーク環境:本番チェーンの状態を写し取った試験用の環境

    まず「守る資産」と「起きてはいけない状態」を決める

    何を守るかを決めずに監視する項目を並べると、どの数字が崩れたら困るのかが分かりません。そこで先に、次のことを結び付けます。

    • 守る対象
    • ふだん成り立っている不変条件と、それが破られたときの最大損失
    • チェーン上で実行できる封じ込め

    起きてはいけないことごとに、見る指標と封じ込めの手を整理すると次のようになります。

    起きてはいけないこと見る指標封じ込めの候補
    資金の流出・会計の不整合1取引・一定時間ごとの純流出、保管庫(vault)の残高、持分価格、総資産と総負債入出庫・借入・発行などを機能ごとに停止、上限を下げる
    価格・オラクルの異常複数の価格源のずれ、更新の遅れ、急な変化の率、流動性新規ポジションと清算を分けて停止、控えめな価格へ切り替え
    権限の侵害ロールの付与・剥奪、所有者の変更、アップグレード・タイムロックの操作、Safe署名者の変更管理用の経路を失効、ガーディアンによる停止、フロントエンドの停止
    依存先の障害ブリッジのメッセージ、シーケンサー、キーパー、RPC、インデクサーの遅れ・食い違い対象のチェーン・資産だけ停止、非同期の処理を保留
    監視そのものの故障最後に処理したブロック、キューの遅れ、死活信号(heartbeat)、通知の配送、ルールの変更安全な上限へ下げる、別の経路で取りこぼし分を取り直す

    異常に気づいた直後に確かめる状態は、後半の「実装する人向けの詳細」にまとめました。

    指標は、攻撃を表すものだけではありません。たとえば、イベントが0件だったとします。利用がないのかもしれません。ノードが遅れている、デコーダーが壊れた、監視ルールが無効になった、のどれでもありえます。そこで、業務の指標と、監視の仕組み自体が健全かを示す指標を別々に持ちます。両方が正常なときだけ「異常なし」と判断します。

    イベントだけでなく、状態の変化と不変条件を見る

    安全にかかわる操作では、イベントを出すようにします。関数、呼び出し元、対象、変更の前後、リクエストIDを追えるようにするためです。

    ただし、イベントはコントラクトが意図して出すログにすぎません。次のようなものは、イベントだけでは表しきれないことがあります。

    • イベントの出し忘れや、アップグレードでのイベントの変更
    • 低レベルの呼び出し
    • selfdestructや強制送金にあたる、チェーン固有の動き

    そのため、定期的な状態の照会、トランザクションのトレース、残高・会計の再計算もあわせて使います。

    不変条件は、監査報告書の文章のままにしておきません。自動で実行できる検査にします。たとえば次のような条件です。

    • 貸付:総借入が、担保とリスクの設定から許される範囲を超えない
    • 保管庫:持分を発行・償還した後も、資産の会計が合っている
    • ブリッジ:送る側のロック・バーンと、受ける側のミント・リリースが、メッセージごとに一度だけ対応する

    検査の結果には、どのチェーンの、どのコントラクトの、どのブロックで、どの版のルールで調べたかを残します。チェーン再編が起きうるので、ブロックの高さだけを根拠にはしません。記録の例は後半に載せました。検査の書き方は不変条件テストの設計で詳しく扱っています。

    監視ツールの事情も変わっています。OpenZeppelin Defender Monitorは、イベント・関数・トランザクションの条件で監視と通知を行うサービスでした。しかしOpenZeppelin Defenderは、2026年7月1日に提供を終えました。

    後継は、オープンソース(AGPL v3)のOpenZeppelin MonitorとOpenZeppelin Relayerです。Dockerイメージなどを使い、自分で動かすことが前提です。自前で動かすと、ノードとの接続、監視条件の版の管理、通知先、取りこぼしの検知と再処理まで、自社の仕事になります。

    Fortaは、検知ボットを動かす監視ネットワークを公開しています。今は、トランザクションを実行前に検査するForta Firewallも提供しています。

    どの製品を使うにしても、受け入れの条件は同じです。ルールが最後に成功したブロック、取りこぼした範囲、再処理の結果を、自社で確かめられること。

    警報の基準は、損失が広がる速さと対応時間から決める

    「100 ETHを超えたら通知」のような固定の値を考えてみます。TVL(プロトコルに預けられた資産の総額)や市場の流動性が変われば、同じ100 ETHでも重みが変わります。固定の値は、そのたびに基準としての意味を失います。基準は、ふだんの値のばらつき、プロトコルの上限、不変条件、気づいてから封じ込めるまでの時間を使って決めます。少なくとも、1回の取引、短い時間、1日の合計、変化の割合を、それぞれ別の基準で見ます。

    最初の設計では、次のように置いて考えます。

    最大追加損失 ≒ 異常時の流出速度 × 検知時間 × 判断・実行時間

    そのうえで、許せる損失を超える前に止められるかを確かめます。たとえば、15分の平均だけを見ていては、1ブロックで終わる攻撃は止められません。

    一方で、大口の取引をすべて最重要として扱うと、当番が疲れ切ります。そこで知らせ方を3つに分けます。すぐに呼び出す、業務時間内にチケットで対応する、ダッシュボードで見るだけにする、です。最重要(Critical)にするのは、影響が大きく、しかもすぐに打てる安全な手があるものに絞ります。

    重大度ごとの分け方は、次のとおりです。

    重大度例最初の動きと、自動で行うこと
    Critical不変条件違反、承認のないアップグレード、急な純流出、管理鍵の侵害を強く示す兆しすぐ呼び出し、インシデントの指揮者を立てる。自動では、事前に承認した上限の引き下げ・対象機能の停止を検討
    Highオラクルのずれ、ロールの変更、ブリッジの遅れ、監視の欠け当番が短い時間で一次の切り分け。自動では、証拠になる状態の記録と、関連する取引の追加トレース
    Medium基準への接近、失敗する取引の増加、キーパーの一部の劣化業務時間内に担当者が確認。自動では、チケット化と傾向の集計
    Info予定していたパラメータ変更、ふだんの大口の移動監査の記録として保存。自動では、変更チケットと突き合わせる

    基準を変えることも、本番の変更です。次のことを記録します。

    • 変える理由、過去データで確かめた期間、誤検知と見逃し
    • 承認者、適用した時刻、元に戻すときの値

    攻撃者が基準を緩める操作そのものも、監視の対象にします。

    通知が届き、判断でき、操作できるかを試す

    警報のルールが正しくても、対応が止まることはあります。通知先のAPIトークンが切れた。スマホの通知が抑えられていた。担当者が異動した。夜中に英語のメッセージが届いた。ダッシュボードを見る権限がなかった。

    そこで監視の仕組みは、端から端まで1つのサービスとして扱います。チェーンのデータ取得から始まり、デコード、ルールの評価、重複の除去、通知、受け取りの確認、上への引き継ぎ(エスカレーション)、インシデントの記録までです。

    • 届くかの試験:作ったイベントや、フォーク環境で流したトランザクションから、呼び出しが届くまでを定期的に流し、端から端までの遅れを測る。
    • 別の経路:主ノードと別のプロバイダー、主なチャットと電話、主なダッシュボードと閲覧専用のエクスプローラーを用意する。同じ障害で一緒に止まらないようにする。
    • 判断に要る情報を付ける:チェーン、アドレス、トランザクション、ルール、重大度、推定の影響、直近の変更、運用手順書、やってはいけない操作を、呼び出しの通知に入れる。
    • 重複をまとめる:1つの攻撃トランザクションから数百件の警報が出ても、1件のインシデントにまとめる。新しい資産・コントラクト・手口は追記する。
    • 欠けたら安全な側へ:死活信号や最後に処理したブロックが遅れたら、「安全」とは扱わない。上限を下げるか、手動の承認に切り替える。

    当番体制の目標は、24時間ダッシュボードを見張ることではありません。重要な兆しが担当者に届き、必要な権限と情報で、時間内に封じ込められることです。外部のSOC(セキュリティ監視センター)や監視サービスに任せても、残るものがあります。停止が事業に与える影響、利用者への告知、鍵の操作、再開の承認は、プロトコル側の責任のままです。

    緊急の権限は「すぐ止める」と「安全に戻す」を分ける

    緊急停止を組み込んでも、実際に止めたときに何が起きるかは、試さないと分かりません。止めたくない返済や清算まで止まってしまうこともあります。試しておくことは次のとおりです。

    • どの関数が止まるか。既にあるポジションの返済・償還・清算まで止まるか
    • 依存先からのコールバックがどうなるか

    全部を一度に止めると、止める必要のない機能まで使えなくなります。そこで、機能ごとの停止を考えます。入金、出金、借入、発行、ブリッジ、アップグレード、フロントエンドなどです。

    冒頭のEulerのように、被害は秒単位で広がることがあります。止めるのは速くなければなりません。一方、戻すのを急ぐと、原因が残ったまま再開してしまうおそれがあります。そこで権限は、止める側と戻す側で重さを変えます。止めるのは秒〜分で、戻すのは慎重に。分け方は次のとおりです。

    操作誰が実行・承認するか
    一部の停止と上限の引き下げ(秒〜分)停止だけに限った専用のガーディアン
    管理鍵と署名者の変更別々の端末で署名するマルチシグと、前もって決めた代わりの署名者
    停止の解除と上限の復元止めた人だけでは戻せない、複数部門の承認
    アップグレードマルチシグ+タイムロック

    使える部品(OpenZeppelin Contracts)は後半にまとめました。停止の単位の決め方、状態の移り方、鍵の分け方、解除の条件はスマートコントラクトの緊急停止設計で詳しく扱っています。

    マルチシグでも、全員が同じ土台に頼っていれば、そこが共通の弱点になります。同じIdP(ログインを管理する認証基盤)、同じPCイメージ、同じパスワード管理ツールなどです。

    SafeのGuardは、トランザクションの実行前後に検査を追加できる仕組みです。ただし公式ドキュメントは、Guardの不具合でSafeそのものを動かせなくなるおそれがあると警告しています。管理アカウント、モジュール、Guard、復旧の手段まで含めて試します。鍵の管理の詳細はSafeのモジュラーアカウント設計もご覧ください。

    事故が起きたら:宣言し、記録し、止め、直し、確かめてから戻す

    NIST SP 800-61 Rev.3は、インシデント対応を組織のリスク管理に組み込む指針です。準備、検知、対応、復旧、改善を回し続けることを求めています。

    チェーン上のインシデントには、これに加える事情があります。トランザクションは取り消せません。公開のメンプール(実行待ちの取引が見える場所)を見て、まねる攻撃(copycat)も出ます。複数のチェーン、管理鍵、Webの基盤が同時にかかわります。運用手順書は、次の7段階で作ります。

    1. 宣言:警報をインシデントIDにまとめる。インシデントの指揮者、セキュリティ責任者、コントラクト責任者、運用担当、広報担当を指名する。
    2. 事実を残す:トランザクションハッシュ、ブロックハッシュ、トレース、コントラクトのコードとストレージ、オラクルの値、RPCの応答、管理操作、フロントエンドのビルド、監視ルールの版を保存する。
    3. 影響を見積もる:影響するチェーン、コントラクト、資産、権限、利用者、最大追加損失を分けて見る。確かめていないことを事実として発表しない。
    4. 封じ込める:前もって決めた条件に沿って対象の機能を止め、鍵・トークンを失効させ、フロントエンド・APIを止める。攻撃者と競うような、試していないトランザクションは送らない。
    5. 取り除く・直す:根本原因、侵入の経路、残っている権限、依存先を突き止め、フォークした状態で修正・移行をやり直してみる。
    6. 復旧する:残高・会計の突き合わせ、コードハッシュ、権限、監視の配送、上限、利用者への案内を再開の条件にして、機能と資産を段階的に戻す。
    7. 事後の振り返り:時系列、判断、気づけた兆し・気づけなかった兆し、損失、修正の担当と期限を事後レビューに残す。

    証拠は、ブロックエクスプローラーのURLや画面写真だけでは足りません。取得した時刻、チェーンID、ブロックハッシュ、生のトランザクションとレシート、トレースの取り方、コントラクトのソースとバイトコードのハッシュを残します。チェーン再編やプロバイダーごとの差があるので、大事なデータは複数の取得元で突き合わせます。

    冒頭のEulerの記録でも、攻撃の後は模倣攻撃、資金の追跡、連絡・交渉が並行しました。技術の調査と外への連絡を、1人に集中させてはいけない理由がよく分かります。

    再開は「直した」ではなく「もう一度起きても止められる」で決める

    原因らしい1行を直しても、同じ攻撃が本当に止まるのか、ほかの処理を壊していないのかは、まだ分かりません。それだけでは再開の条件を満たしません。フォーク環境か本番に近い環境で、攻撃のトランザクションをもう一度流し、次の4つを確かめます。

    • 修正後は攻撃が失敗すること
    • 正常な処理・清算・償還などを壊していないこと
    • 同じ攻撃を監視が検知すること
    • 停止と解除の役割分担が働くこと

    再開の時点では、次のものを記録に固定します。

    • 対象のチェーンとブロック、残高・負債・持分の供給量、未処理のメッセージ
    • コントラクトの実装とコードハッシュ、すべてのロールと署名者、承認額(allowance)
    • オラクル・キーパーの状態、監視ルール、分かっている残りのリスク、承認者

    再開した後は、小さな上限と限られた資産から始めます。一定の期間に異常がないことを確かめてから、段階的に広げます。新しい異常や監視の欠けが出たら、1つ前の安全な段階に戻せなければなりません。

    訓練と目標値で、損失を止める力を測る

    警報が鳴ったかどうかではなく、損失を止められるかを測ります。四半期ごとなどの定期の演習に加え、次の変更の前後でも想定の場面をやり直します。アップグレード、署名者の変更、チェーンの追加、オラクル・ブリッジの変更、監視プロバイダーの変更です。机の上の演習だけでなく、フォーク環境やリスクの低い試験用コントラクトで、警報から停止まで通します。

    • 不変条件違反をわざと起こし、平均検知時間(MTTD: Mean Time To Detect)と平均封じ込め時間(MTTC: Mean Time To Contain)を測る。
    • 主なRPC、主な通知先、当番の担当者を同時に使えなくし、代わりの経路が働くか確かめる。
    • ガーディアンの署名者1人の端末が侵害されたと見なし、署名の定足数(quorum)と鍵の更新を実行する。
    • 誤検知で止めてみて、利用者への影響を測りながら安全に戻せるか試す。
    • チェーン再編を起こし、警報の取り消し・評価のやり直しと、証拠のブロックハッシュを確かめる。
    • 夜に事業責任者がいなくても、停止の権限と告知の判断を代わりに担う順番が働くか確かめる。

    運用の目標値(SLO:サービスの水準について決めた目標)は、次の項目で持ちます。

    • 監視の範囲、最後に処理したブロックの遅れ
    • 重大な警報が届いた割合、受け取りを確認するまでの時間、緊急停止にかかる時間
    • 解決していないHighの警報、運用手順書の演習の成功率

    平均だけでなく、p95/p99(遅いほうから5%・1%の境目の値)と最悪の値も見ます。チェーン別・時間帯別にも分けます。基準を緩めれば誤検知は減りますが、そのぶん本物の攻撃も見逃しやすくなります。そのため、過去のインシデントや模擬の攻撃を流し直したときの検知率も、あわせて見ます。

    どこまで外に任せられるかは、欠けを補えるかで決める

    監視ルール、ノード、トレースの解析、当番、フォレンジック(証拠の調査・分析)を、すべて自社で持つ必要はありません。ただし外部のサービスが警報を出しても、プロトコル固有の不変条件、停止が利用者に与える影響、緊急の鍵、外への説明、再開の承認までは引き受けてくれません。

    領域ごとに、自社で持つか外に頼るかの目安は次のとおりです。

    領域自社で持つのが向く条件外部を使うのが向く条件
    チェーンデータ・トレース独自のチェーン・VM、遅れの少なさ、深い状態の解析が必要標準的なEVMと、一般的なイベントが中心
    検知ルール独自の会計・経済モデルが中心にあるロールの変更・大口の移動などの共通ルール
    24時間の一次の切り分け十分な当番の人数と、プロトコルの知識がある夜間の一次の切り分けを補いたい
    インシデント対応変更が多く、すぐの操作が必要フォレンジック・交渉・法務などの専門性を補う

    外に任せても、自社に残る責任は次のとおりです。

    • チェーンデータ・トレース:欠けの検知、プロバイダーの切り替え、証拠の保全
    • 検知ルール:不変条件、基準の値、変更の承認、検証用のデータ
    • 24時間の一次の切り分け:重大度、引き継ぎの順番、停止の判断
    • インシデント対応:インシデントの指揮、利用者の保護、復旧の承認

    費用は、ツールの利用料だけでは見積もれません。ルールの開発、ノード・RPC、ログの保管、当番の手当、演習、誤検知への対応、鍵・端末、外部のフォレンジック、停止中の事業の損失まで含めます。

    24時間対応できない、停止を安全に実行できない、復旧を確かめられない。そうした場合は、高額の資産を扱う機能や、取り消せない自動実行を採用しない判断も必要です。

    本番に出す前の受け入れ基準

    • 全コントラクト・チェーン・プロキシの実装・管理アカウントの一覧と担当者がある。
    • 重要な不変条件ごとに兆候、データの取得元、ルール、重大度、運用手順書、封じ込め操作が対応している。
    • 監視の死活信号、最終処理ブロック、チェーン再編、取りこぼしの再取得、通知配送を試験している。
    • 重大アラートから当番、インシデント指揮者、ガーディアンまでの連絡と代理順序がある。
    • 停止対象と残す機能、依存先、利用者影響、解除の条件を試験している。
    • 管理鍵・マルチシグ署名者・端末・IdP・復旧用情報に共通障害点がない。
    • トランザクション、トレース、状態、コードハッシュ、判断ログを改変されにくい場所へ保全できる。
    • 既知の攻撃と監視の欠損を注入し、MTTD/MTTCと最大追加損失が許容範囲に収まる。
    • 外部サービス停止時の代替データ取得元と最低限の手動手順がある。
    • 段階復旧、残高照合、監視の再試験、利用者告知の承認者が決まっている。

    この基準を満たせない機能は、リスクを小さくしてから出します。本番で扱う資産の上限を下げる。取り消せる処理に変える。手動の承認を残す。公開を延ばす。このどれかです。

    実装する人向けの詳細

    ここからは、監視と停止の仕組みを実際に組む開発・運用の担当者向けに、前半で後回しにした中身をまとめます。

    異常に気づいたら、すぐ確かめる状態

    失敗条件すぐ確認する状態
    資金流出・会計不整合同一ブロック内の呼び出しトレース、受取先、オラクル値、直前のアップグレード
    価格・オラクル異常最終更新ブロック、代替の価格源、清算候補額
    権限侵害実行者、提案から実行までの間隔、署名者の端末、コードハッシュ
    依存先障害複数の接続先、チェーンのファイナリティ、処理中のメッセージ
    監視そのものの故障ノード同期、チェーン再編の処理、別プロバイダーとのブロック高の差

    不変条件の検査結果の記録例

    検査結果には、チェーンID、コントラクトアドレス、実装のコードハッシュ、ブロック番号とハッシュ、ルールの版を保存します。支払能力の検査が破れたときは、証拠と運用手順書の番号を付けて記録します。

    {
      "rule_id": "vault-solvency-v3",
      "scope": {"chain_id": 1, "contract": "0x..."},
      "observed_at": {"block_number": 0, "block_hash": "0x..."},
      "predicate": "assets + receivables >= liabilities",
      "result": "BREACH",
      "evidence": ["state_snapshot", "trace_set", "price_snapshot"],
      "runbook": "IR-SC-04"
    }

    停止と権限に使える部品

    • Pausable:_pauseと_unpauseを呼べる権限を、使う側が決める部品。
    • AccessControlDefaultAdminRules:default adminの移管を、1人・2段階・遅延付きに制限する。
    • TimelockController:保守の操作を遅らせて実行する。

    関連記事

    本番に出す前の変更管理はスマートコントラクトのリリース管理、アップグレード権限とタイムロックの設計はスマートコントラクトのアップグレード設計で扱っています。監査の工程とリリース前の評価はスマートコントラクト監査の工程と費用目安、Account Abstraction固有の攻撃面はAAセキュリティリスクにまとめています。

    XTELAができること

    私たちは、スマートコントラクトとオフチェーンのサービスをまたぐ脅威モデル、不変条件、監視ルール、アラートの経路、緊急停止と権限の設計を、動く仕組みとして設計・開発します。OpenZeppelin Monitorなどを使った自前監視の構築や、フォーク環境でのインシデント演習を貴社の本番構成に合わせてPoC(概念実証)から一緒に進められます。運用要件を実装できる設計へ落としたい場合はお問い合わせフォームからご連絡ください。

    主要参考資料

    資料の確認日と注意

    一次資料は2026年8月12日に確認しました。OpenZeppelin DefenderとFortaの提供状況は、2026年9月24日に確認し直しています。一般的な技術・運用設計の解説で、法務・規制・保険・投資の助言ではありません。個別の判断は、公式の仕様と資格を持つ専門家に確認してください。

    お問い合わせ

    どんなフェーズからでも、お持ちのアイデアや企画をもとにご提案可能です。
    まずはお気軽にご相談下さい!