[EIP3085] ウォレットに新しいチェーンを追加する標準インターフェースの仕組みを理解しよう！

# はじめに

初めまして。
**CryptoGames**というブロックチェーンゲーム企業でエンジニアをしている **cardene（かるでね）** です！
スマートコントラクトを書いたり、フロントエンド・バックエンド・インフラと幅広く触れています。

https://cryptogames.co.jp/

代表的なゲームは**クリプトスペルズ**というブロックチェーンゲームです。

https://cryptospells.jp/

今回は、イーサリアムウォレットに新しいチェーンを追加する標準インターフェースである`wallet_addEthereumChain`メソッドを提案している**EIP3085**についてまとめていきます！

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

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

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

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

# 概要

イーサリアムのウォレットに新しいチェーン（ブロックチェーンネットワーク）を追加するための標準的な方法を提供する提案です。

通常、イーサリアムウォレットは、イーサリアム本体のブロックチェーンとやりとりしますが、イーサリアムエコシステムには複数のブロックチェーン（例えば、テストネットや異なるイーサリアムベースのネットワークなど）が存在します。
ユーザーや開発者がこれらの異なるチェーンをウォレットで簡単に使えるようにするには、ウォレットがそれらのチェーンに接続し、操作を行う方法を知っている必要があります。

ここで提案されている`wallet_addEthereumChain`は、ウォレットに新しいチェーンを追加するための「**名前空間付きRPCメソッド**」です。
RPC（Remote Procedure Call）メソッドとは、ネットワーク上の別のプログラム（この場合はイーサリアムウォレット）に対して、特定の操作を実行するようリクエストする仕組みのことです。
名前空間とは、メソッドや機能を分類するための仕組みで、ここでは「`wallet_`」というプレフィックスがついています。

このメソッドを使うことで、ウォレットは開発者やユーザーからのリクエストを受け取り、新しいチェーンの情報（例えば、チェーンの名前、RPCエンドポイント、シンボル、ブロックエクスプローラのURLなど）をウォレットに追加します。
これにより、ウォレットは追加されたチェーン上でトランザクションを送信したり、そのチェーンの資産を管理することができるようになります。

:::note info
このEIPはイーサリアムウォレットがさまざまなイーサリアムベースのブロックチェーンと容易にやり取りできるようにするための標準的な方法を提供することを目指しています。
これにより、エコシステム全体の相互運用性が向上し、ユーザー体験が改善されます。
:::

# 仕様

この提案では、新しいRPCメソッドである`wallet_addEthereumChain`を定義しています。

## `wallet_addEthereumChain`パラメータ

提案された`wallet_addEthereumChain`メソッドについての詳細を解説します。このメソッドは、イーサリアムウォレットに新しいチェーンを追加することを提案するために使用されます。基本的に、ウォレットのチェーンリストに新しいブロックチェーンを加えることを提案し、そのプロセスには特定のパラメータが必要です。

### 概要

- **パラメータ**
    - このメソッドは`AddEthereumChainParameter`オブジェクトを1つのパラメータとして受け取ります。
- **戻り値**
    - チェーンの追加に成功した場合は`null`を返し、追加されなかった場合はエラーを返します。

### `AddEthereumChainParameter`オブジェクトの詳細

このオブジェクトは以下のフィールドを持っています。

- **chainId**
    - チェーンの整数IDを16進数文字列で表します。
    - **EIP155**に従います。

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

https://qiita.com/cardene/items/2526432899353e4a0225

- **blockExplorerUrls**
    - ブロックエクスプローラのURLの配列です。
    - 有効なURLでなければなりません。
- **chainName**
    - チェーンの名前を示した文字列です。
- **iconUrls**
    - チェーンのアイコン画像のURLの配列です。
    - 有効な画像へのURLでなければなりません。
- **nativeCurrency**
    - チェーンのネイティブ通貨に関する情報を含むオブジェクトです。
    - **EIP20**のように解釈されます。

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

https://chaldene.net/erc20

- **rpcUrls**
    - チェーンのRPCエンドポイントのURLの配列です。
    - 有効なURLでなければなりません。

### ウォレットの要件

ウォレットは、以下の条件に基づいてリクエストを受け入れるか拒否する必要があります。

- **chainId**が有効な16進数文字列でない、または有効なチェーンIDでない場合、リクエストは拒否されます。
- **rpcUrls**が提供されていない、または空の配列の場合、リクエストは拒否されます。
    - また、無効なURLが含まれている場合も拒否されます。
- **nativeCurrency**が提供されている場合、`name`、`symbol`、`decimals`の各フィールドが必要です。
    - `decimals`が負の整数である場合、リクエストは拒否されます。
- **blockExplorerUrls**と**iconUrls**が提供されており、有効なURLでない場合、リクエストは拒否されます。
- `file:`や`http:`スキームを使用するURLは拒否されます。

:::note info
このメソッドはイーサリアムウォレットに新しいチェーンを追加する際の標準化された方法を提供し、特定の要件を満たす必要があることを規定しています。
これにより、ユーザーや開発者はウォレットを介して複数のイーサリアムベースのブロックチェーンと簡単にやり取りできるようになります。
:::

### `wallet_addEthereumChain`の戻り値

`wallet_addEthereumChain`メソッドの戻り値に関する説明です。

### 成功とエラーの戻り値
- **成功時の戻り値**
    - メソッドがリクエストを成功裏に処理した場合、`null`を返す必要があります。
    - これは、新しいチェーンがウォレットのリストに追加されたことを意味します。
- **エラー時の戻り値**
    - リクエストが何らかの理由で失敗した場合、メソッドはエラーを返す必要があります。
    - ウォレットは任意の理由でリクエストを拒否することができます。
    - これは、技術的な問題、セキュリティ上の懸念、またはユーザーによる拒否など、さまざまな理由によるものかもしれません。

### チェーンの自動選択
ウォレットはリクエストを拒否しなかったとしても、新しく追加されたチェーンが自動的に選択されるとは限りません。
ウォレットはユーザーによる手動選択を要求するか、または追加されたチェーンを利用する前に追加のアクションを要求することがあります。

### 既に追加されたチェーンの取り扱い
既に追加されているチェーンを再度追加しようとするリクエストは、原則として成功するべきです。
ただし、ユーザーがリクエストを拒否した場合や検証に失敗した場合はこの限りではありません。

### 同一の`chainId`の重複追加の禁止
ウォレットは、同じ`chainId`を持つチェーンを複数回追加することを許可してはいけません。
これはセキュリティ上の配慮からであり、混乱を避け、悪意のある行為を防ぐためです。
例えば、偽のチェーンを追加しようとする攻撃を防ぐことができます。

### セキュリティ上の考慮事項
提案文書では、「**セキュリティ上の考慮事項**」セクションで、このメソッドの安全な使用に関するさらなる詳細や推奨事項が提供されている可能性があります。
これには、重複追加の禁止のような特定のルールのほか、データの検証、ユーザーとの対話方法、信頼できる情報源からのデータのみを使用することなどが含まれるかもしれません。

以上のガイドラインに従うことで、ウォレットはユーザーにより安全かつ効率的なサービスを提供することができます。
これらの原則は、ユーザー体験の向上とセキュリティリスクの最小化を目的としています。

# 補足

`wallet_addEthereumChain`メソッドの設計では、ウォレットにチェーンを「追加」する意味を意図的に無視しています。
チェーンをウォレットに追加するは、ウォレットの実装によって異なります。
これには、ウォレットが新しいチェーンをどのように認識し、ユーザーインターフェースに表示するか、またチェーンとのインタラクションの方法など、多くの側面が含まれます。

### `chainId`の必要性
`chainId`は、イーサリアムチェーンの宇宙において、**EIP155**チェーンIDが実質的にチェーンのGUID（グローバル一意識別子）として機能するため、メソッドを呼び出す際には常に指定する必要があります。
これは、異なるイーサリアムチェーンを識別するための重要な手段です。

### その他のパラメータの役割
残りのパラメータは、ウォレットがチェーンを効果的にサポートし、ユーザーに代表させるために最小限必要とされるものと推定されます。
ネットワークIDは、チェーンIDによって事実上置き換えられているため、省略されています。

### セキュリティとメタデータの検証
セキュリティ上の理由から、ウォレットはリクエスターから提供されたチェーンメタデータを常に検証しようとするべきであり、場合によってはメタデータを完全に別の場所から取得することを選択するかもしれません。
どのチェーンメタデータが必要かは、ウォレットによってのみ知られています。
そのため、`chainId`を除くすべてのパラメータはオプションとして指定されていますが、実際にはウォレットがそれらを要求することがあります。

### アクティブチェーンの「切り替え」について
この仕様は、成功したリクエストの後でウォレットが「**アクティブ**」または「**現在選択されている**」チェーンを「**切り替える**」ことを要求しません。
チェーンを「**追加**」する意味やチェーン間を「**切り替える**」ことは、ウォレットの実装詳細であり、したがって範囲外です。

この設計は、ウォレットが異なるイーサリアムチェーンとどのようにやり取りするかに関して柔軟性を持たせることを目的としています。
これにより、ウォレット開発者は自身の製品の機能、ユーザーインターフェース、セキュリティ要件に最適な方法でチェーンを統合することができます。
また、ウォレットがユーザーにより多くの選択肢と制御を提供することを可能にします。

# セキュリティ

`wallet_addEthereumChain`メソッドのセキュリティ上の考慮事項について、その重要なポイントを詳しく解説します。
このメソッドは非常に強力で、誤った実装によりエンドユーザーを深刻なリスクにさらす可能性があるため、セキュリティに関する厳格なガイドラインが必要です。

### チェーンIDの扱い
- **チェーンIDの検証**
    - トランザクション署名に使用されるチェーンIDが、トランザクションが有効なチェーンを決定します。
    - ウォレットは提出されたチェーンIDが有効であることを確認し、**EIP695**に従って`0x`接頭辞付きの16進数文字列であり、整数に解析できることを保証する必要があります。

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

https://qiita.com/cardene/items/02ec9ef125808a70a4d5

- **重複の防止**
    - 同じチェーンIDが複数回追加されないようにする。
- **署名時のチェーンIDの使用**
    - トランザクションを署名するためには、提出されたチェーンIDのみを使用し、RPCエンドポイントから受け取ったチェーンIDを使用してはなりません。
    - 悪意のあるまたは不良のエンドポイントが任意のチェーンIDを返し、ユーザーが意図しないチェーンのためにトランザクションを署名する可能性があります。
- **チェーンIDの一致の検証**
    - 指定されたチェーンIDがエンドポイントからの`eth_chainId`の戻り値と一致することを確認します。

### RPCエンドポイントとRPC URL
ウォレットは通常、RPCエンドポイントを介してチェーンとやり取りします。
多くのウォレットは、信頼できるRPCエンドポイントと対応する一連のチェーンを搭載しています。
`rpcUrls`パラメータによって識別されるエンドポイントが正直であるとは限らず、正しいとも、同じチェーンを指しているとも限りません。
ウォレットは、ユーザーのオンチェーン活動とIPアドレスがRPCエンドポイントに公開されること、未知のエンドポイントが予期しない方法で振る舞う可能性があることをユーザーに知らせる必要があります。
HTTPSを要求するなど、エンドポイントとのやり取りにおいて良好なウェブセキュリティ実践を観察する必要があります。

### チェーンデータの検証
`wallet_addEthereumChain`を実装するウォレットは、ウォレット保守者に完全に未知のチェーンのためのリクエストに遭遇することを期待するべきです。
しかし、多くのイーサリアムチェーンのリクエストを検証するために活用できるコミュニティリソースが存在します。
ウォレットは既知のチェーンのリストを維持し、そのリストに対してチェーンを追加するリクエストを検証するべきです。
実際、ウォレットは`wallet_addEthereumChain`リクエストで提出されたものよりも自身のチェーンメタデータを好むかもしれません。

これらのセキュリティ上の考慮事項は、ウォレットがエンドユーザーを保護し、信頼性の高いサービスを提供するための基盤を形成します。
ウォレット開発者はこれらのガイドラインを厳格に守ることで、ユーザーが安全にウォレットを使用できるようにする責任があります。

`wallet_addEthereumChain`メソッドを使用する際のユーザーエクスペリエンス（UX）に関する指針とプライバシーの保護について説明します。これらの指針は、ウォレットの機能性とユーザー体験に重要な影響を与える新しいチェーンの追加プロセスを案内するものです。

### ユーザー確認の提示
- 新しいチェーンをウォレットに追加する際は、ユーザーの明示的な同意が必要です。`wallet_addEthereumChain`リクエストを受け取った際には、特定のリクエスターがチェーンの追加をリクエストしたことをユーザーに知らせる確認画面を表示する必要があります。これにより、ユーザーは自分のウォレットに影響を与える変更について十分に理解し、同意することができます。

### チェーンメタデータの活用
- チェーンのメタデータ（例えば、`nativeCurrency`や`blockExplorerUrls`）は、ウォレットのUIで最大限に活用するために検証されるべきです。これにより、ユーザーはウォレット内で操作しているチェーンの特性を正確に理解することができます。

### アイコンと表現
- `iconUrls`を通じて提供された画像がある場合、ウォレットはユーザーに対してこれらのアイコンが実際に追加されたチェーンを誤って表現する可能性があることを理解させる必要があります。これは、ユーザーが見た目だけでチェーンを判断するのを防ぐためです。

### アクティブチェーンの選択
- ウォレットUIが「現在選択されている」または「現在アクティブな」チェーンの概念を持っている場合、`wallet_addEthereumChain`を使用して追加されたチェーンが選択されたときにユーザーがそれを理解できるようにする必要があります。

### ユーザープライバシーの保護
- 既に追加されたチェーンを追加するリクエストは、一般的には成功とみなすべきですが、そのようなリクエストを自動的に成功とみなすことは、リクエスターに対してユーザーがウォレットに追加したチェーンに関する情報を漏洩させる可能性があります。ユーザープライバシーを保護するために、`wallet_addEthereumChain`の実装者は、これらのケースでもユーザー確認を表示することを検討するべきです。ユーザーがリクエストを拒否した場合、ウォレットは通常どおりユーザー拒否エラーを返すべきであり、これによりリクエスターはユーザーの明示的な許可なくウォレットがサポートするチェーンについて学ぶことができません。

これらのガイドラインは、ユーザーがウォレット内での新しいチェーンの追加に関する意思決定を行

う際に、情報に基づいた選択を行えるようにするために重要です。また、ユーザープライバシーを尊重し、セキュリティリスクを最小限に抑えることにも貢献します。

# 引用

Erik Marks (@rekmarks), Pedro Gomes (@pedrouid), Pandapip1 (@Pandapip1), "EIP-3085: wallet_addEthereumChain RPC Method [DRAFT]," Ethereum Improvement Proposals, no. 3085, November 2020. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-3085.

# 最後に

今回は「イーサリアムウォレットに新しいチェーンを追加する標準インターフェースである`wallet_addEthereumChain`メソッドを提案している**EIP3085**」についてまとめてきました！
いかがだったでしょうか？

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

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

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

https://chaldene.net/

https://zenn.dev/heku

https://mirror.xyz/0xcE77b9fCd390847627c84359fC1Bc02fC78f0e58

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