[ERC7618] データが返される前に指定されたアルゴリズムでデコードする仕組みを理解しよう！

# はじめに

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

https://cryptogames.co.jp/

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

https://cryptospells.jp/

今回は、**ERC5219**のresolveモードで、圧縮されたリソースをクライアントに渡す前にデコードする仕組みを提案している**ERC7618**についてまとめていきます！

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

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

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

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

# 概要

この規格は、**ERC6860**のweb3URL標準の文脈において、**ERC6944**のresolveモードを拡張する仕組みを提案しています。

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

https://qiita.com/cardene/items/30bdd75be892cf776b88

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

https://qiita.com/cardene/items/c8f906536dcb7fe7492d


`request()`呼び出しによって、**Content-Encoding**ヘッダーが返された場合に、返されたデータがクライアントに返される前に指定されたアルゴリズムに従ってデコードすることを提案しています。

:::note info
この規格は以下の**ERC7617**と似ているので、合わせて読むと理解が深まるかもしれないです。
:::

https://qiita.com/cardene/items/e834423ba74beecb433b

# 動機

ブロックチェーンにおいてストレージは高価であるため、データを圧縮して保存・提供することが最適です。

:::note info
「**ストレージが高価**」とは以下のようなことを意味しています。

#### トランザクションコスト
ブロックチェーンにデータを書き込む時、各トランザクションごとにガス代がかかります。
ガス代はデータの量やネットワークの混雑状況に応じて変動しますが、大量のデータを保存する場合は高額になります。

#### ストレージ書き込み制限
ストレージにデータを書き込むとき、大量のデータを一度に書き込むことができずエラーになってしまいます。
:::

標準HTTPでは、クライアントがサポートしている圧縮アルゴリズムのリストをサーバー側に渡し、その中から1つのメカニズムで圧縮されたデータを返す、**Accept-Encoding/Content-Encoding**メカニズムが使用されます。
正し、**web3://**プロトコルにそのまま適用することは、ブロックチェーンのストレージと計算の制約により最適ではないです。
また、固定の**Content-Encoding**ヘッダを使用してコンテンツを提供することは、HTTPクライアントがその圧縮アルゴリズムをサポートしていない可能性があるためできないです。

この問題を解決するために以下のアプローチが提案されています。

- **対応圧縮アルゴリズムのリストの指定**
    - クライアントがサポートしている圧縮アルゴリズムのリストをプロトコル側で指定。
- **プロトコル側での解凍**
    - 圧縮されたデータをプロトコル側で解凍しクライアントに提供。

このアプローチにより、圧縮データを安全に保存してクライアントが対応する形で提供することができます。

# 仕様

**ERC6944**は、**web3://**プロトコルにおけるコンテンツ圧縮と解凍に関する標準を定めています。

### Content-Encodingの検査とデコード

クライアントが送信したリクエストに**Accept-Encoding**ヘッダーが含まれていないか、または**Content-Encoding**ヘッダーに指定された圧縮アルゴリズムがクライアントの**Accept-Encoding**ヘッダーに含まれていない場合、プロトコルはコンテンツをデコードしてからクライアントに転送します。
プロトコルでは以下の圧縮アルゴリズムをサポートします。
- gzip
- br (brotli)

### 非対応の圧縮アルゴリズムの処理
コンテンツの**Content-Encoding**ヘッダーに指定された圧縮アルゴリズムが、プロトコルのサポートリストに含まれていない場合、プロトコルは「**サポートされていないコンテンツエンコーディング**」を示すエラーをクライアントに送信しなければなりません。

### デコード後のデータ送信
コンテンツがデコードされた後、解凍されたデータをクライアントに送信します。
このとき、送られた**Content-Encoding**ヘッダーを含めてクライアントに送信してはいけません。

## 実際の処理フロー

1. **クライアントからのリクエスト受信**
    - クライアントが**web3://**プロトコルを使ってリクエストを送信。
    - このリクエストに**Accept-Encoding**ヘッダーが含まれている場合、そのヘッダー内の圧縮アルゴリズムが指定されています。

2. **サーバからのレスポンス受信**
    - サーバがレスポンスを返し、このレスポンスに**Content-Encoding**ヘッダーが含まれている場合、そのデータが特定の圧縮アルゴリズムで圧縮されています。

3. **プロトコルによるデコード**
    - プロトコルはレスポンスの**Content-Encoding**ヘッダーをチェックします。
    - クライアントの**Accept-Encoding**ヘッダーと照合し、サポートされていない場合や**Accept-Encoding**ヘッダーが無い場合、プロトコルはデータをデコードします。

4. **エラーハンドリング**
    - デコードが必要な場合、指定された圧縮アルゴリズムが**gzip**または**br**でない場合、プロトコルはエラーをクライアントに返します。

5. **クライアントへのデータ送信**
    - デコード後、**Content-Encoding**ヘッダーを除去したデータをクライアントに送信します。

# 補足

この機能はインターフェースを変更せずに追加できるため、**ERC6944**`resolve`モードに追加しました。
標準HTTPにできるだけ近づけるため、新しいHTTPヘッダーを導入するのではなく既存の**Content-Encoding**ヘッダーを利用しています。

# 引用

Qi Zhou (@qizhou), Nicolas Deschildre (@nand2), "ERC-7618: Content encoding in ERC-5219 mode Web3 URL [DRAFT]," Ethereum Improvement Proposals, no. 7618, February 2024. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-7618.

# 最後に

今回は「**ERC5219**のresolveモードで、圧縮されたリソースをクライアントに渡す前にデコードする仕組みを提案している**ERC7618**」についてまとめてきました！
いかがだったでしょうか？

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