﻿---
title: "クロスチェーンメッセージのリプレイ保護"
description: "クロスチェーンのリプレイ保護は、認証済みの送信元メッセージを一つのプロトコル版と宛先ドメインへ結び付け、再試行を許しながら成功した経済効果を一度に限定します。"
image: "https://wiki.fcontext.com/og.png"
---

> Documentation Index
> Fetch the complete documentation index at: https://wiki.fcontext.com/llms.txt
> Use this file to discover all available pages before exploring further.

# クロスチェーンメッセージのリプレイ保護

> 教育目的の情報であり、投資助言ではありません。リプレイ制御の欠陥は、重複した発行、ロック解除、任意の宛先呼び出しを引き起こし、回収不能な損失につながる場合があります。

<a id="answer"></a>

## 要点

クロスチェーンメッセージのリプレイ保護は、認証済みの送信元メッセージが意図した宛先ドメインで成功する経済効果を一度以下にします。リレイヤーは同じ証明を繰り返し配信でき、失敗した試行は再試行できる場合がありますが、完了済みメッセージが再び発行、ロック解除、受信者呼び出しを行ってはなりません。

真正性、ファイナリティ、リプレイ保護は別々の検査です。有効な署名、バリデーター証明、ストレージ証明はデータを認証できても、送信元イベントの確定、意図した宛先と受信者の拘束、宛先での未処理までは証明しません。同様に、認可リレイヤーは配信経路にすぎず、その身元をメッセージ認証の代わりにはできません。

普遍的なクロスチェーン `messageId` はありません。シリアライズと識別方法は個別プロトコル仕様が定めます。堅牢なエンベロープは通常、プロトコルと版、送信元ドメインとメッセンジャーまたはエミッター、送信元送信者、nonce または送信元取引・ログの識別情報、宛先ドメインと受信者、価値、ペイロード、有効期限を結び付けます。Wormhole、CCTP、Optimism、ERC-5164 は異なるフィールドと状態機械を使うため、識別子を相互に流用できません。

<a id="mechanism"></a>

## 仕組み

送信元の操作がメッセージを発行または保存します。必要な確認またはファイナリティ方針を満たした後、バリデーター、ガーディアン、証明システムが認証します。宛先では、検証器が適切なルートまたは署名集合、プロトコル版、信頼済みリモート送信者、宛先、受信者、ペイロード、時間制約を確認します。受信者は仕様所定の識別子を導出し、外部効果を生む前に永続的な処理済み状態を照会します。

配信は多くの場合 at-least-once ですが、望ましい業務効果は実質一度です。有用な状態機械は、未試行、処理中、失敗または再試行可能、成功または消費済みを区別します。宛先呼び出しの失敗は自動的にリプレイ攻撃とはなりません。例えば ERC-5164 は、メッセージの成功実行を最大一度にしつつ、失敗後の再試行を認めます。製品固有の再試行規則、Gas 処理、価値会計は別途支配します。

リプレイフラグまたは処理ガードは、信頼できない外部呼び出しより前に設定し、リエントランシーを制御します。取引全体が revert すれば、その状態変更も通常 revert し、明確な再試行経路が残ります。下流の失敗を意図的に捕捉するプロトコルは、部分的な価値や効果を誤って残さず、独立した失敗状態を記録しなければなりません。下流システムを別経路から呼べる場合、受信側も冪等にします。

nonce のスコープは重要です。連番 nonce は順序を強制しますが、一つの欠落で後続メッセージをすべて止め得ます。順不同 nonce またはビットマップは独立配信を可能にする一方、ワードとビットを正確に計算する必要があります。バッチは、全体がアトミックか、各リーフに独立した証明と処理済み状態があるかを定めます。部分実行後にバッチルートだけを消費済みにすると、成功リーフを重複させるか、失敗リーフを取り残しかねません。

送信元の再編成方針もリプレイ安全性の一部です。十分なファイナリティ前に署名された観測は、後に送信元イベントが非正規になっても暗号学的には有効なままの場合があります。アップグレードも境界です。プロキシのストレージレイアウト、処理済みマッピング、版ドメイン、旧エントリーポイント、対向先のローテーション、フォークまたは chain ID の再利用は、消費済みメッセージを再開せず、従来の識別子を保存するか意図的に無効化しなければなりません。

次の手順を使います。

1. プロトコル、デプロイ版、送信元と宛先のドメイン、信頼済みメッセンジャーまたはエミッター、送信者、受信者、価値、ペイロード、nonce またはイベント識別情報、有効期限の意味を固定する。
2. 仕様の正規エンコーディングと `messageId` テストベクトルを再現する。曖昧な連結、欠落フィールド、別ブリッジから借用した仮定を拒否する。
3. 送信元への取り込みと必要なファイナリティまたは確認方針を検証し、正しい証明ルート、署名クォーラム、バリデーターまたはガーディアン集合、版を検証する。
4. 宛先、受信者、クロスドメイン送信者、価値、ペイロード、有効期限を個別に検証する。提出リレイヤーは権限主体ではなく輸送手段として扱う。
5. 永続的なメッセージ状態を読み、信頼できない外部呼び出しより前に処理中または消費済みへ移す。リエントランシー保護を設け、取引 revert の挙動を明示的に試験する。
6. 成功、失敗、再試行可能の遷移、連番またはビットマップ nonce、バッチの原子性、価値会計を定義し、重複配信が成功済みリーフの効果を繰り返さないことを証明する。
7. アップグレード、ストレージ移行、無効化した旧入口、対向先ローテーション、フォーク、緊急復旧を試験し、レシート、イベント、処理済み状態、宛先残高を照合する。

<a id="example"></a>

## 例

- **宛先ドメインの拘束。** 2件の指図はいずれも nonce `42`、価値 `1,000` ですが、一方はチェーン `10`、他方はチェーン `8453` 宛てです。宛先を省いた識別子は `2 messages` を同じ衝突候補として扱いますが、宛先を結び付けた正規エンコーディングは `2 distinct IDs` を生成します。実際のハッシュ関数とドメイン表現はプロトコルに従います。
- **順不同ビットマップ。** nonce `513` では、`word = floor(513 / 256) = 2`、`bit = 513 mod 256 = 1`、`mask = 1 << 1 = 2` です。最初の成功でビットマップワード `2` は `0` から `2` になります。重複時は `2 & 2 = 2` となり拒否され、nonce `512` は独立してビット `0` を使います。
- **再試行は二度目の効果ではない。** 同じ認証済みメッセージが `3` 回配信されます。宛先呼び出しは `110,000` と `125,000` Gas で失敗して revert し、3回目は `140,000` Gas で一度だけ成功します。総 Gas は `110,000 + 125,000 + 140,000 = 375,000`、`20 gwei` なら `0.0075 ETH` です。配信は `3` 回でも、成功した業務効果は `1` 回です。
- **部分バッチの会計。** 独立実行可能な4リーフは `25 + 40 + 15 + 20 = 100` 単位を持ちます。リーフ `0`、`1`、`3` は成功して `25 + 40 + 20 = 85`、リーフ `2` は失敗して `15` が未処理です。バッチルートだけを消費すると `15` が取り残され、リーフ状態なしに全体を再試行すると `85` が重複し得ます。仕様に従い、アトミックな巻き戻しまたはリーフ単位の処理済み状態を使います。

<a id="risks"></a>

## リスク

- 識別子に宛先チェーンまたはドメインがない。
- 識別子に送信元メッセンジャーまたはエミッターがない。
- ドメインにプロトコル版またはメッセージ版がない。
- nonce 名前空間が送信者またはデプロイ間で衝突する。
- 曖昧な packed encoding で異なるフィールド構成が衝突する。
- フォークまたは再利用された chain ID で旧ドメインが再び有効になる。
- 十分なファイナリティ前に受理した送信元イベントが再編成で消える。
- 誤った証明ルート、バリデーター集合、ガーディアン集合を受理する。
- アップグレード後も旧署名ドメインが有効である。
- プロキシのストレージ破損で処理済み状態がリセットまたは混同される。
- 移行で消費済みメッセージが漏れるか、旧入口が残る。
- 外部呼び出し後に状態を記録し、リエントランシーを許す。
- 失敗した呼び出しを成功扱いし、再試行不能になる。
- 成功した呼び出しを永続化せず、経済効果が反復する。
- 欠落した連番 nonce が後続をすべて止める。
- ビットマップのワード、ビット、無効化計算を誤る。
- バッチルート状態とリーフ単位の部分実行が矛盾する。
- 再試行が成功済みリーフを再実行する。
- deadline、expiry、宛先時計の単位を誤読する。
- リレイヤーの許可リストをメッセージ認可と誤認する。

<a id="misconceptions"></a>

## よくある誤解

- **nonce だけで全世界に一意になる。** 名前空間は送信者、プロトコル、デプロイ、送信元と宛先のドメインで決まります。
- **認可リレイヤーだけがリプレイを防ぐ。** リレイヤーは配信を担い、宛先検証と永続的な消費済み状態が認可とリプレイ制御を担います。
- **重複配信はすべて攻撃である。** at-least-once ネットワークは失敗メッセージを再試行できます。不変条件は成功効果が一度以下であることです。
- **有効な証明や署名はファイナリティと意図を証明する。** 意図した宛先が欠けたり、誤った版を拘束したり、後に再編成される送信元状態を証明したりする場合があります。
- **ブリッジ取引の成功で exactly-once 完了を証明できる。** バッチの全リーフを含め、レシート状態、処理済みストレージ、受信者イベント、実残高を確認します。

<a id="related"></a>

## 関連トピック

- [クロスチェーンブリッジ](/ja/crypto/cross-chain-bridge/)
- [カノニカルブリッジ](/ja/crypto/canonical-bridge/)
- [クロスチェーンリレイヤーの障害](/ja/crypto/bridge-relayer-liveness-risk/)

<a id="sources"></a>

## 出典

- [ERC-5164: Cross-Chain Execution](https://eips.ethereum.org/EIPS/eip-5164) - Ethereum Improvement Proposals（参照日：2026-08-13）
- [EIP-712: Typed structured data hashing and signing](https://eips.ethereum.org/EIPS/eip-712) - Ethereum Improvement Proposals（参照日：2026-08-13）
- [CCTP Technical Guide](https://developers.circle.com/cctp/references/technical-guide) - Circle Developers（参照日：2026-08-13）
- [Interop message passing overview](https://docs.optimism.io/app-developers/guides/interoperability/message-passing) - Optimism Documentation（参照日：2026-08-13）
- [VAAs](https://docs.wormhole.com/protocol/infrastructure/vaas/) - Wormhole Docs（参照日：2026-08-13）
- [Security Considerations](https://docs.soliditylang.org/en/latest/security-considerations.html) - Solidity Documentation（参照日：2026-08-13）
- [Proof-of-stake (PoS)](https://ethereum.org/developers/docs/consensus-mechanisms/pos/) - ethereum.org（参照日：2026-08-13）
- [Upgrading smart contracts](https://docs.openzeppelin.com/contracts/5.x/learn/upgrading-smart-contracts) - OpenZeppelin Docs（参照日：2026-08-13）

Source: https://wiki.fcontext.com/ja/crypto/bridge-message-replay-protection/index.mdx
