[EIP234] Ethereumログ取得のフィルターオプションにブロックハッシュを追加する提案を理解しよう！

# はじめに

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

https://cryptogames.co.jp/

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

https://cryptospells.jp/

今回は、EthereumのJSON-RPCフィルターオプションに、特定のブロックハッシュを指定してログを取得する機能を追加する提案をしている**EIP234**についてまとめていきます！

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

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

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

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

# 概要

EthereumのJSON-RPC APIにおけるフィルターオプションの改善提案についてです。
具体的には、イベントログを取得する時に使用される`eth_newFilter`や`eth_getLogs`といったメソッドに、新しいフィルターオプションを追加する提案です。
この新しいオプションにより、特定のブロックハッシュに基づいてログをフィルタリングすることが可能になります。

## 現行の問題点
現在、イベントログを取得する時には`fromBlock`や`toBlock`といったオプションを使って、取得するブロックの範囲を指定します。
しかし、この方法にはいくつかの問題があります。

- **チェーン再編成(Reorgs)**
    - Ethereumではブロックチェーンの再編成が発生することがあり、これにより取得したログが最新のチェーンに含まれない可能性があります。
- **ネットワークの不安定性**
    - 不安定なネットワーク接続により、特定のブロックのログを取得することが困難になる場合があります。
- **空の結果セット**
    - 現在の方法では、結果セットに十分な詳細が含まれない場合があり、クライアントが正確な情報を得ることが困難になります。

## 提案された改善点
提案では、フィルターオプションに`blockHash`という新しいパラメータを追加することを提案しています。
これにより、ユーザーは特定のブロックハッシュを指定してログをフィルタリングできるようになり、以下のメリットが期待できます。

- **特定ブロックの精密なフィルタリング**
    - ブロックハッシュによる指定により、正確にそのブロックのログのみを取得できるようになります。
- **チェーン再編成の問題の緩和**
    - ブロックハッシュによる指定であれば、再編成によってもそのブロックのログを正確に取得できます。
- **堅牢なクライアントの開発を支援**
    - このオプションにより、開発者はより信頼性の高いEthereumクライアントを開発できるようになります。

## まとめ
この提案は、Ethereumのイベントログ取得機能をより柔軟かつ信頼性の高いものにするためのものです。
`blockHash`オプションの追加により、特定のブロックに対するログの取得が容易になり、チェーンの再編成やネットワークの不安定性による問題を軽減できると期待されます。

# 動機

提案された内容は、EthereumのJSON-RPC APIの一部である`eth_newFilter`メソッドのフィルターオプションに、新たに`blockHash`というオプショナルなパラメータを追加することについてです。この`blockHash`パラメータは単一のブロックハッシュの値を取り、以下のように機能します。

## `blockHash`の役割
ユーザーが`eth_newFilter`を使用してイベントログをフィルタリングする時に、特定のブロックハッシュを指定できるようになります。
指定されたブロックハッシュがEthereumノードに存在する場合、そのノードはフィルター条件に一致する結果を、指定されたブロックに限定して返します。
もし指定されたブロックハッシュが見つからない場合は、エラーを返します。

## 機能の仕組み
内部的には、`fromBlock`や`toBlock`のような既存のフィルターオプションと似たように機能すると考えられますが、結果は指定された単一のブロックに限定されます。
この機能により、開発者は特定のブロックで発生したイベントのみを精密にフィルタリングして取得することが可能になります。

### 利点
特定のブロックに対するイベントログを正確に取得できるため、データの精度が向上します。
ブロックチェーンの再編成（リオーグ）が発生した場合でも、特定のブロックハッシュに基づいてログを取得できるため、データの一貫性を保つことができます。
ネットワークの不安定性やその他の問題が発生しても、特定のブロックに対するログを確実に取得できるため、アプリケーションの堅牢性が向上します。

この提案により、Ethereumのイベントログの取得方法がより柔軟で信頼性の高いものになることが期待されます。

# 補足

この説明では、ブロックチェーンのクライアント（特に分散アプリケーション、dApp）が直面する一般的な問題と、その解決策について話しています。
問題は、新しいブロックが追加された時のログの通知と、ブロックチェーンの再編成（リオーグ）が発生した時のログの削除通知を、信頼性高く受け取ることが困難である点にあります。
再編成とは、ブロックチェーン上であるブロックが別のブロックに置き換わることを指し、これによって以前に確認されたトランザクションが無効になることがあります。

## 問題点
- **ネットワークやノードの障害**
    - クライアントがWebsocketsなどの接続を使用してログのフィルターサブスクリプションを設定しているときに、接続が失われ、その間に再編成が発生するとクライアントはログの削除通知を受け取れなくなります。
- **フィルター状態の喪失**
    - HTTPクライアントの場合、アップデートのポーリング間にノードがダウンし、復旧した時にフィルター状態が失われると、クライアントは再編成による変更を認識できなくなります。

## 解決策
- **内部ブロックチェーンの維持**
    - クライアントが内部的に最後のnブロックを維持し、新しいブロックのみをサブスクライブまたはポーリングすることで、どのような切断/再編成/障害シナリオにも対応できます。
    - 新しいブロックを受け取るたびに、内部モデルを新しいブロックと照合し、必要に応じて親ブロックを補充するか、ブロックをロールバック/削除してノードと同期します。
- **ブロックハッシュによるログのフェッチ**
    - ログをブロック番号ではなく、ブロックハッシュに基づいてフェッチする機能を追加することで、クライアントが受け取る結果セットが求めているブロックのものであることを保証できます。
    - これにより、結果セットが空の場合でも、どのブロックの結果であるかを正確に知ることができ、適切なアクション（例えば、クライアント側でそのブロックをロールバックし、最新のものを再フェッチする）を取ることができます。

この提案により、クライアントはブロックチェーンの変更に対してより堅牢に対応できるようになり、特に再編成が頻繁に発生する可能性のある環境での信頼性が向上します。
ブロックハッシュに基づいてログをフェッチする機能は、クライアントが正確な情報を得るための重要なステップとなります。

# 互換性

Ethereumのフィルターオプションに関する潜在的な問題について述べています。
具体的には、`fromBlock`と`toBlock`のフィールドと、新しく提案された`blockHash`フィールドの使用についての問題です。

## 現状のフィルターオプション
`fromBlock`と`toBlock`は、イベントログをフィルタリングする際に、特定のブロック範囲を指定するために使用されます。
`blockHash`（提案された新しいオプション）は、特定のブロックハッシュを指定して、そのブロックに対するログのみをフィルタリングするために使用されることが提案されています。

## 問題点
`blockHash`と`fromBlock`/`toBlock`を同時に使用することは意味がありません。
なぜなら、`blockHash`は単一のブロックを指定するものであり、`fromBlock`と`toBlock`はブロックの範囲を指定するものだからです。
そのため、`blockHash`オプションが使用されている場合、`fromBlock`と`toBlock`は無視されるべき、または使用されないべきです。
これは、フィルタリングの対象が単一のブロックに限定されるためです。

## 解決策
`fromBlock`/`toBlock`と`blockHash`を相互に排他的にする必要があります。
つまり、フィルターオプションとして一方を使用する場合は、他方を使用できないようにするべきです。
これにより、フィルタリングオプションの使用に関する混乱を避けることができ、APIの使いやすさと明確さが向上します。

この提案は、Ethereumクライアントがフィルターオプションをより効果的かつ明確に使用できるようにするためのものです。
ブロック範囲に基づくフィルタリングと、特定のブロックハッシュに基づくフィルタリングの間で明確な区別を設けることで、開発者が目的に合ったフィルタリング戦略を簡単に選択できるようになります。

# テスト

EthereumのJSON-RPCリクエストの一例と、それがどのように機能するかについてのテストです。
`eth_getLogs`メソッドを使用して、特定のブロックハッシュに関連するログを取得する方法についてテストしています。

```bash
{ "jsonrpc": "2.0", "id": 1, "method": "eth_getLogs", params: [{"blockHash": "0xbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0c"}] }
```

## JSON-RPCリクエストの構造
- `jsonrpc`
    - 使用するJSON-RPCのバージョンを示します。
    - ここでは"2.0"が使用されています。
- `id`
    - リクエストを一意に識別するためのIDです。
    - 応答でこのIDが返され、リクエストと応答を関連付けるのに使われます。
- `method`
    - 実行したいJSON-RPCメソッドの名前です。
    - この例では、`eth_getLogs`が使用されています。
- `params`
    - メソッドに渡すパラメータの配列です。
    - この例では、`blockHash`が含まれており、特定のブロックハッシュを指定しています。

## リクエストの動作
指定された`blockHash`に対応するブロックのすべてのログを返します。
この例では、ブロックハッシュが`0xbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0c`です。
`topics`フィールドがフィルターオプションに追加された場合、そのトピックに基づいてフィルタリングされたログのセットが返されます。
指定されたハッシュを持つブロックが存在しない場合、エラーが返されます。
このエラーには、エラーコード`-32000`、エラーメッセージ`"Block not found."`、そしてエラーの詳細を示すデータ（この場合は指定されたブロックハッシュ）が含まれます。

このリクエストと応答のメカニズムにより、開発者はEthereumブロックチェーン上の特定のブロックに関連するログ情報を正確に取得できるようになります。
これは、スマートコントラクトのイベントを追跡したり、特定のブロックの状態を分析したりする際に非常に役立ちます。

# 引用

Micah Zoltu (@MicahZoltu), "EIP-234: Add `blockHash` to JSON-RPC filter options.," Ethereum Improvement Proposals, no. 234, March 2017. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-234.

# 最後に

今回は「EthereumのJSON-RPCフィルターオプションに、特定のブロックハッシュを指定してログを取得する機能を追加する提案をしている**EIP234**」についてまとめてきました！
いかがだったでしょうか？

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