# [ERC7930] クロスチェーン取引を安全にするためにチェーンIDをアドレスを含む仕組みを理解しよう！

> Interoperable Addressesは、特定のブロックチェーンに固有のアドレスを表現するためのバイナリ形式です。これにより、人間が読みやすい表示用の仕様「Interoperable Names」と組み合わせて利用できます。

- URL: https://cardene.dev/articles/a0475affba1edb342a9f
- 公開日: 2025-08-19
- 更新日: 2025-08-19
- トピック: Blockchain
- タグ: ethereum, solidity, smartcontract, ブロックチェーン

## はじめに

『DApps開発入門』という本や色々記事を書いているかるでねです。

https://amzn.asia/d/gxvJ0Pw

今回は、異なるブロックチェーン間でアドレスを誤りなく識別・利用できるよう、チェーン情報とアドレスを統一的に扱うバイナリ形式と人間が読みやすい読形式を定めた標準を提案している**ERC7930**についてまとめていきます！

:::message
以下にまとめられているものを翻訳・要約・補足しながらまとめていきます。
:::

https://eips.ethereum.org/EIPS/eip-7930

他にも様々なEIPについてまとめています。

https://cardene.notion.site/ERC-EIP-2a03fa3ea33d43baa9ed82288f98d4a9?pvs=4

## 概要

Interoperable Addressesは、特定のブロックチェーンに固有のアドレスを表現するためのバイナリ形式です。
これにより、人間が読みやすい表示用の仕様「**Interoperable Names**」と組み合わせて利用できます。
**ERC7930**では、バージョン情報と長さ情報を持つバイナリエンベロープを使い、可変長のデータを格納します。
内部のデータ構造や変換ルールは、各チェーンごとのプロファイルとして別途定義されます。
この仕組みによって、EVMチェーンだけでなく、非EVMチェーンのアドレスも統一的に表現でき、クロスチェーンの資産移動やメッセージパッシングに適した標準フォーマットが実現されます。

## 動機

従来のEthereumアドレス（**ERC55**）には、次のような問題があります。
まず、チェックサムが任意であるため、ユーザーがアドレスを誤入力しても検出されない可能性があります。
また、アドレス自体にチェーン情報が含まれず、外部の情報に依存してチェーンを識別しなければならないため、誤ったチェーンでアドレスを使うリスクがあります。
特に、スマートコントラクトアドレスでは、このリスクは高くなります。
さらに、既存の形式には拡張の仕組みがなく、これらの機能を自然に追加する手段もありません。

:::message
**ERC55**については以下の記事を参考にしてください。
:::

[\[EIP55\] Ethereumアドレスのチェックサムの仕組みを理解しよう！](/articles/985f03760df12929b5f9)

Interoperable Addressesは、こうした課題を解決するために、以下の要素を組み込みます。

* 明確なチェーン識別子によるアドレスの紐付け
* クロスチェーン通信やインテントの宣言に適したコンパクトで正規化されたバイナリ形式
* 名前の衝突やユーザー入力ミスを防ぐためのチェックサム

この設計によって、同一アドレスは常に同じバイナリ表現になり、比較や検証が容易になります。
また、非EVMチェーンも含めてアドレス形式を統一できるため、クロスチェーンの資産移動やメッセージ連携の基盤として機能します。

### 他規格との比較

**CAIP10**はテキスト形式でアドレスを表現する標準ですが、バイナリ形式での正規化やデータ効率は考慮されていません。
そのため、同じ実体を持つ複数の異なる表記が存在し得ます。
さらに、スマートコントラクトやクロスチェーンメッセージングで重要なデータ効率や厳密な一致判定には不向きです。
Interoperable Addressesは、バイナリ形式を基盤にしており、テキスト形式への変換（Interoperable Namesや**CAIP10**互換）も可能です。これにより、既存のエコシステムとの後方互換性を保ちつつ、将来的なクロスチェーン相互運用性を強化できます。

## 仕様

### 基本概念

Interoperable Addressesは、異なるブロックチェーン間で誤解なくアドレスを扱えるようにするためのバイナリ形式です。
この仕組みでは、機械が正確に処理できるバイナリ形式と、人間が読みやすい文字列形式（Interoperable Names）を組み合わせます。
ここで使われる主要な用語は次の通りです。

* **Interoperable Address**
    * 対象アドレスを一意に特定できるバイナリデータで、人間可読形式に変換可能。
* **Interoperable Name**
    * Interoperable Addressを人間が読める文字列として表現したもの。
* **Target address**
    * 特定のアドレスとチェーンIDを組み合わせた情報。

### バイナリ形式（V1）の構造

Interoperable Address V1は、以下の順序でデータを構成します。

```
┌─────────┬───────────┬──────────────────────┬────────────────┬───────────────┬─────────┐
│ Version │ ChainType │ ChainReferenceLength │ ChainReference │ AddressLength │ Address │
└─────────┴───────────┴──────────────────────┴────────────────┴───────────────┴─────────┘
```

* **Version**
    * 2バイトのバージョン識別子。
    * V1では`0x0001`（ビッグエンディアン）を使用します。
    * 将来のバージョンは別のERCで標準化されます。
* **ChainType**
    * 2バイトの値で、**CAIP350**に基づく**CAIP2**の名前空間を表します。
    * これにより、後続のフィールドの解釈方法が決まります。
* **ChainReferenceLength**
    * 1バイトで、`ChainReference`の長さをバイト数で示します。
    * 0でも構いませんが、その場合はチェーン参照が含まれません。
* **ChainReference**
    * 可変長のバイナリデータで、**CAIP2**のチェーン識別子を**CAIP350**のルールに従ってシリアライズしたものです。
* **AddressLength**
    * 1バイトで、`Address`の長さを示します。
    * `ChainReferenceLength`と同時に0であってはいけません。
* **Address**
    * 可変長のアドレス本体をバイナリで格納します。
    * 形式はチェーンタイプに依存します。

この構造により、アドレスとチェーン情報をセットで扱えるため、誤ったチェーンでの使用を防げます。

### バージョン互換性のルール

将来のバージョンでも一貫性を保つために、いくつかの制約があります。
例えば、V1と互換性のない形式にする場合はバージョンフィールドの最上位ビットを1にすること、全てのバージョンでアドレスとチェーン指定を同時に扱えること、チェックサム計算時はV1形式に変換してバージョンフィールドを除外することなどが求められます。

### Interoperable Nameの形式

人間が読むための形式は以下の構造を持ちます。

```
<address> @ <chain> # <checksum>
```

* **address**
    * チェーン固有のアドレス文字列表現。
    * `AddressLength`が0の場合は空文字になります。
* **chain**
    * **CAIP2**のブロックチェーン識別子の文字列表現。
    * `ChainReferenceLength`が0の場合は名前空間のみを記載します。
* **checksum**
    * 4バイトのチェックサムで、バイナリデータ（Version以外）をkeccak256でハッシュ化し、先頭4バイトを16進数（**RFC4648**準拠）で表現します。

この構造により、人間が視覚的にチェーンとアドレスの関係を確認でき、かつ短いチェックサムで誤りを検出できます。

## 補足

### フィールド構造の理由

Interoperable Addressesでは、チェーン情報とアドレス情報を表すための文字列構造が意図的に設計されています。
アドレスとチェーンの区切りには「`@`」を使い、これにより「`:`」を自由に使用できるようにしています。
これによって、**CAIP2**の名前空間や**CAIP10**のアカウントIDを表現でき、長いアドレス形式や256ビットのEVMチェーンIDなども対応可能になります。
さらに、アドレス部分には「`%`」を使えるようにしており、URLエンコードによる特殊文字の表現も可能です。

### なじみのある形式を選んだ理由

技術的には、base58やbase64などのエンコード方式を採用すれば、情報効率を高めたりチェーン情報を抽象化することもできます。
しかし、**ERC7930**ではあえて馴染みのある文字列形式を採用しています。
理由は、ユーザーが**Interoperable Address**と元の生アドレスの関係を直感的に理解できるようにするためです。
もし、あるウォレットやdAppがInteroperable Addressをまだサポートしていなくても、ユーザーは「**アドレス部分は同じで、チェーンとチェックサムが省略されているだけ**」と判断できます。
この見慣れた構造による可読性は、将来チェーン名やアドレス名に特化した標準が整備されるまでのつなぎとしても役立ちます。

### ゼロ長アドレス・チェーンID対応の理由

Interoperable Addressesは、アドレスやチェーンIDがゼロ長（空）の場合も許容します。
これにより、1つの標準で以下の両方を統一的に表現できます。

* クロスチェーンメッセージの宛先など、未知のチェーン上のアドレス
* 単なるアドレスやチェーンIDだけを表す用途（例：クロスチェーンメッセージの送信元フックアドレス指定）

この設計により、異なる実装間でも形式の統一性が保たれ、運用がシンプルになります。

## テストケース

ここでは、Interoperable Addresses仕様に沿って作成された具体的な例を使い、EthereumやSolanaなど異なるチェーンのアドレスをどのように表現できるかを説明します。
それぞれの例では、人間が読むための形式（Interoperable Name）と、機械が扱うためのバイナリ形式（Interoperable Address）の両方を示し、フィールドの構造やチェックサム計算の方法を確認します。

### 例1：Ethereumメインネットのアドレス

Ethereumメインネットのアドレスを表すケースです。
Interoperable Nameは、アドレス・チェーン識別子（eip155:1）・チェックサムを組み合わせて表現します。
バイナリ形式では、バージョン（`0x0001`）、チェーンタイプ（eip155を示す値）、チェーン参照（ID=1）、アドレス長（20バイト）、アドレス本体という順に格納します。
チェックサムは、Versionフィールドを除外したバイナリデータをkeccak256でハッシュ化し、その先頭4バイトを16進数にしたものです。

```
0x00010000010114D8DA6BF26964AF9D7EED9E03E53415D37AA96045
  ^^^^-------------------------------------------------- Version:              decimal 1
      ^^^^---------------------------------------------- ChainType:            2 bytes of CAIP namespace
          ^^-------------------------------------------- ChainReferenceLength: decimal 1
            ^^------------------------------------------ ChainReference:       1 byte to store uint8(1)
              ^^---------------------------------------- AddressLength:        decimal 20
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Address:              20 bytes of ethereum address
```

### 例2：Solanaメインネットのアドレス

Solanaメインネットのアドレスは32バイトの長さを持ちます。
Interoperable Nameでは、アドレス文字列とチェーン識別子（solana:ソラナのジェネシスブロックID）を組み合わせ、最後にチェックサムを付与します。
バイナリ形式では、バージョン、チェーンタイプ（Solanaを示す値）、32バイトのチェーン参照、アドレス長（32バイト）、アドレス本体の順に格納します。
この構造により、EVM以外のチェーンでも統一的な方法でアドレスを表現できます。

```
0x000100022045296998a6f8e2a784db5d9f95e18fc23f70441a1039446801089879b08c7ef02005333498d5aea4ae009585c43f7b8c30df8e70187d4a713d134f977fc8dfe0b5
  ^^^^---------------------------------------------------------------------------------------------------------------------------------------- Version:              decimal 1
      ^^^^------------------------------------------------------------------------------------------------------------------------------------ ChainType:            2 bytes of CAIP namespace
          ^^---------------------------------------------------------------------------------------------------------------------------------- ChainReferenceLength: decimal 32
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------------------------------------------------------------------ ChainReference:       32 bytes of solana genesis block
                                                                            ^^---------------------------------------------------------------- AddressLength:        decimal 32
                                                                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- Address:              32 bytes of solana address
```

### 例3：EVMアドレス（チェーンIDなし）

この例では、EVMのアドレスは指定されていますが、チェーンIDは省略されています。
Interoperable Nameでは、アドレスとチェーン名前空間（eip155）だけを記載し、チェックサムを付けます。
バイナリ形式では、チェーン参照長が0となり、その後にアドレス長（20バイト）とアドレス本体が続きます。
この表現は、チェーンが明確に決まっていない場合や、単にアドレスだけを共有する場合に有効です。

```
0x000100000014D8DA6BF26964AF9D7EED9E03E53415D37AA96045
  ^^^^------------------------------------------------ Version:              decimal 1
      ^^^^-------------------------------------------- ChainType:            2 bytes of CAIP namespace
          ^^------------------------------------------ ChainReferenceLength: zero, indicating no chainid
            ^^---------------------------------------- AddressLength:        decimal 20
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Address:              20 bytes of ethereum address
```

### 例4：Solanaメインネット（アドレスなし）

このケースでは、チェーンはSolanaメインネットですが、アドレスは指定されていません。
Interoperable Nameは「**@チェーン識別子#チェックサム**」という形になり、アドレス部分は空です。
バイナリ形式では、チェーンタイプとチェーン参照（32バイト）を含め、アドレス長を0としています。
この形式は、アドレスではなくチェーン自体を指定する場合や、特定のチェーン上での宛先が未確定な状態でのメッセージ送信に利用できます。

## セキュリティ

### 完全な一意性が保証されない可能性

Interoperable Addressesは、本来どのチェーンのアドレスも一意に参照できるように設計されています。
しかし、現実の運用では必ずしも完全な一意性（カノニカリティ）が保証されるわけではありません。
例えば、特定のチェーン名前空間が採用するアドレスのシリアライズ（変換）方式が、複数の異なる表記を同じアドレスとして認識してしまう場合があります。
また、同じネットワークを指しているにもかかわらず、異なる**CAIP2** IDが存在するケースもあり得ます。

### 実装者への注意点

もし実装者がアドレスの完全な一意性を前提として利用する場合（例：スマートコントラクトのマッピングやキー・バリュー型データベースでのキーとして使用する場合）、事前の確認が必要です。
具体的には、対象チェーンの**CAIP350**プロファイルを精査し、アドレスのカノニカリティが保証されているかを確認することが推奨されます。
このプロファイルには、追加の注意事項（Extra Considerations）として、カノニカリティの欠如や既存の他の名前空間との衝突の可能性が記載されているはずです。

## 引用

Teddy (@0xteddybear), Joxes (@0xJoxess), Nick Johnson (@Arachnid), Francisco Giordano (@frangio), Skeletor Spaceman (@skeletor-spaceman), Racu (@0xRacoon), TiTi (@0xtiti), Gori (@0xGorilla), Ardy (@0xArdy), Onizuka (@onizuka-wl), Sam Kaufman (@SampkaML), Marco Stronati (@paracetamolo), Yuliya Alexiev (@yuliyaalexiev), Jeff Lau (@jefflau), Sam Wilson (@samwilsn), Vitalik Buterin (@vbuterin), "ERC-7930: Interoperable Addresses [DRAFT]," Ethereum Improvement Proposals, no. 7930, February 2025. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-7930.

## 最後に

今回は「」についてまとめてきました！
いかがだったでしょうか？

質問などがある方は以下のTwitterのDMなどからお気軽に質問してください！

[Twitter @cardene777](https://twitter.com/cardene777)

他の媒体でも情報発信しているのでぜひ他も見ていってください！

https://chaldene.net/

https://zenn.dev/heku

https://cardene.substack.com/

https://mirror.xyz/0xcE77b9fCd390847627c84359fC1Bc02fC78f0e58

https://cardene.notion.site/ERC-EIP-2a03fa3ea33d43baa9ed82288f98d4a9?pvs=4
