[EIP695] EthereumのJSON-RPCにチェーンIDを取得できる機能を追加する提案を理解しよう！

# はじめに

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

https://cryptogames.co.jp/

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

https://cryptospells.jp/

今回は、EthereumのJSON-RPCインターフェイスに`eth_chainId`メソッドを追加する提案をしている**EIP695**についてまとめていきます！

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

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

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

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

# 概要

`eth_chainId`は、EthereumのJSON-RPC仕様の一部で、現在接続されているブロックチェーンの識別子、つまり`CHAIN_ID`を取得するために使われるメソッドです。
この`CHAIN_ID`は、トランザクションに署名する時に、同じトランザクションが異なるチェーン上で再実行される（リプレイ攻撃）のを防ぐために導入されたものです。
これは**EIP155**（Ethereum Improvement Proposal 155）で提案されました。

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

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

`eth_chainId`メソッドが呼び出されると、現在接続しているEthereumネットワークの`CHAIN_ID`を表す16進数の文字列が返されます。
例えば、Ethereumメインネットの`CHAIN_ID`は`0x1`、Ropstenテストネットの場合は`0x3`となります。

この`CHAIN_ID`は、スマートコントラクトの実行やトランザクションの署名において、どのブロックチェーンネットワークを対象としているのかを明確にするために重要です。
また、開発者はこのメソッドを使用して、自分のアプリケーションやサービスが正しいEthereumネットワークに接続されていることを確認できます。

# 動機

Ethereumには、`net_version`というRPC(リモートプロシージャコール)メソッドがあり、これを使うと現在接続しているEthereumネットワークのIDを取得できます。
しかし、ネットワークIDだけでは、実際に接続しているブロックチェーンがどれであるかを完全には特定できません。

ネットワークIDとチェーンIDは異なる概念です。
ネットワークIDは主にノード間のピアリング（接続）に使われる一方で、チェーンIDはトランザクションの署名に使われ、リプレイ攻撃を防ぐために導入されました。
このため、同じネットワークIDを持つ異なるブロックチェーンが存在する可能性があります。

ここで指摘しているのは、現在のEthereumのRPCインターフェースには、このチェーンIDを直接問い合わせる方法がないため、RPCを通じて実際にどのブロックチェーンに接続しているのかを確認することができないという問題です。
これは、特に複数のEthereumベースのネットワークを扱うアプリケーションやサービスにとって、適切なネットワークに接続しているかを確認する上で重要な情報が不足していることを意味します。
この問題を解決するためには、チェーンIDを問い合わせるための新しいRPCメソッドが必要になります。

# 仕様

`eth_chainId`はEthereumのJSON-RPCインターフェースを通じて、現在設定されているチェーンIDを取得するために使用されます。
チェーンIDは、**EIP155**によって導入されたリプレイ攻撃から保護されたトランザクション署名に使用される値です。

このメソッドが返すチェーンIDは、常に現在知られている最新のヘッドブロックの情報に対応しているべきです。
これにより、このRPCメソッドの呼び出し元は、常に取得した情報を使用して、最新のヘッドブロックの上に構築されたトランザクションに署名できるようになります。

もし現在知られている最新のヘッドブロックがチェーンIDを指定していない場合、クライアントは`eth_chainId`メソッドの呼び出しをサポートしていないかのように扱い、適切なエラーを返すべきです。

このメソッドはパラメータを必要とせず、現在のチェーンIDを16進数で表した値を返します。
例えば、`curl -X POST --data '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":83}'` のようなコマンドを使用してこのメソッドを呼び出すと、結果として`{"id": 83, "jsonrpc": "2.0", "result": "0x3d"}`が返されます。
この場合、`"result": "0x3d"`は、チェーンIDが61であることを表しています（16進数の`0x3d`は10進数で61に相当します）。

```bash
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":83}'

// Result
{
  "id": 83,
  "jsonrpc": "2.0",
  "result": "0x3d" // 61
}
```

# 補足

Ethereum (ETH) と Ethereum Classic (ETC) は異なるブロックチェーンですが、元々は同じブロックチェーンでした。
2016年に発生した分岐により、これら二つの異なるネットワークが誕生しました。
両者は似たような構造を持っており、同じ通信プロトコルを使用しているため、ETHのクライアントが間違ってETCのRPCエンドポイントに、またはその逆に接続する可能性があります。

ただし、トランザクションを署名する際や、特定のチェーンIDで署名されたことが既知のトランザクションをフェッチする時にのみ、クライアントは自分が誤ったネットワークに接続していることに気づくことができます。
なぜなら、ETHとETCでは異なるチェーンIDを使用しているため、誤ったネットワークでトランザクションを署名しようとするとエラーが発生するからです。

このような状況は、複数のチェーンをサポートしようとするアプリケーション開発者、例えばMetaMaskのようなウォレットサービスを提供する開発者にとって問題を引き起こしています。
開発者はユーザーが意図せずに誤ったネットワークに接続していないかどうかを常に確認し、適切なネットワークに接続していることを保証する必要があります。
これには追加のチェックとロジックが必要で、開発の複雑さを増しています。

# セキュリティ

Ethereumのブロックチェーンと通信する時に、ネットワークを正確に識別するためのベストプラクティスについて説明しています。
具体的には、`eth_chainId`メソッドを`net_version`メソッドよりも優先して使用するべきだと述べています。

## `eth_chainId`の重要性
`eth_chainId`メソッドは、**EIP155**に基づいて導入された、リプレイ攻撃を防ぐためのチェーンIDを提供します。
このIDはトランザクションが特定のチェーンに特有であることを保証し、他のチェーンでのトランザクションの再実行（リプレイ攻撃）を防ぎます。
このため、`eth_chainId`を使用することで、開発者やユーザーは自分たちが通信しているブロックチェーンを正確に識別できます。

## `net_version`の限界
`net_version`メソッドは、ネットワークのIDを提供しますが、これはチェーンIDとは異なり、リプレイ攻撃の防止には直接関係しません。
また、異なるチェーンが同じネットワークIDを使用する可能性があり、このためにネットワークを正確に識別するのには適していません。

### 実装者への呼びかけ
`eth_chainId`の実装者（例えば、ブロックチェーンノードの開発者やウォレットサービスの提供者）は、このメソッドを正確に実装し、その使用を促進することが求められます。
これは、`eth_chainId`がセキュリティ上非常に重要な役割を果たし、消費者が通信しているチェーンを識別するために信頼するからです。

:::note info
`eth_chainId`はチェーンの識別において重要な役割を果たし、セキュリティ上の利点も提供するため、その使用が推奨されています。
これにより、開発者とユーザーは自分たちが意図したブロックチェーンと正しく通信していることを確信できます。
:::

# 参考

EthereumのJSON RPCインターフェースにおける「`QUANTITY`」の戻り値のエンコーディング方法について言及しています。
Ethereum Wikiで文書化されている通り、標準のJSON RPC 16進数値エンコーディングに従います。

「`QUANTITY`」とは、数値を表す時に使われるデータタイプの一つで、EthereumのRPC通信において頻繁に使用されます。
このエンコーディング規則に従うことで、Ethereumネットワークと通信する際のデータの整合性と互換性が保たれます。

16進数値エンコーディングとは、数値を16進数形式（`0x`をプレフィックスとして使用）で表現する方法です。
例えば、10進数の16は16進数では「`0x10`」と表されます。
この形式は、Ethereumのトランザクション、スマートコントラクトのアドレス、ガスの価格、トランザクションのノンスなど、多くのパラメータや戻り値で採用されています。

Ethereum Wikiでは、このエンコーディング方式に関する詳細なルールが定められており、Ethereumの開発者やユーザーは、これらのルールに従ってデータをエンコードまたはデコードする必要があります。
これにより、異なるシステムやアプリケーション間でのデータの互換性と一貫性が確保されます。

# 引用

Isaac Ardis <isaac.ardis@gmail.com>, Wei Tang (@sorpaas), Fan Torchz (@tcz001), Erik Marks (@rekmarks), "EIP-695: Create `eth_chainId` method for JSON-RPC," Ethereum Improvement Proposals, no. 695, August 2017. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-695.

# 最後に

今回は「EthereumのJSON-RPCインターフェイスに`eth_chainId`メソッドを追加する提案をしている**EIP695**」についてまとめてきました！
いかがだったでしょうか？

質問などがある方は以下の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