[ERC5219] GETリクエストのみの効率的なDapp通信の仕組みを理解しよう！

# はじめに

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

https://cryptogames.co.jp/

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

https://cryptospells.jp/

今回は、GET（読み取り専用）のインターフェースを通じて、効率的なDapp通信を提案している**ERC5219**についてまとめていきます！

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

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

# 概要

このEIP（Ethereum Improvement Proposal）は、スマートコントラクトへのリソースリクエストとHTTPに似たレスポンスの受け取りを標準化するインターフェースを提供します。

# 動機
Ethereumは、分散型アプリケーション（DApp）を構築するための最も確立されたブロックチェーンです。
そのため、Ethereum DAppエコシステムは非常に多様です。
しかし、DAppに対する一つの問題は、それらが完全に分散化されていないということです。
具体的には、「**分散化された**」アプリケーションとインターフェースするためには、まずDAppのフロントエンドコードを含む中央集権のウェブサイトにアクセスする必要があります。
これにはいくつかの問題があります。

以下は、中央集権のウェブサイトを使用して分散化されたアプリケーションに接続する際のリスクです。

### 信頼の最小化

通常、中央集権的なアプリケーションでは、ユーザーはそのアプリケーションを提供する企業やサービスプロバイダに対して信頼を置かなければなりません。
しかし、分散型アプリケーション（DApp）の場合、複数のエンティティが関与し、そのすべてを信頼する必要があります。
これは、個人情報や資金のセキュリティなどの面で懸念を引き起こすことがあります。

### 検閲
中央集権のウェブサイトは、その運営者がコンテンツを検閲したり制限したりすることが可能です。
これによって、情報の自由や表現の自由が制約を受ける可能性があります。
一方、分散型アプリケーションでは、データやコードが分散して保存されるため、一つの中央機関による検閲のリスクが低くなります。

### 永続性
通常のウェブインターフェースは、サーバー上にホストされており、運営者が意図しない変更を加える可能性があります。
そのため、インターフェースの内容や機能が変わってしまう可能性があります。
分散型アプリケーションでは、インターフェース自体がブロックチェーン上に保存されることがあり、永続性が確保される可能性が高くなります。

### 相互運用性
通常のアプリケーションとスマートコントラクトは、異なる環境で動作するため、直接的な対話が難しいことがあります。
分散型アプリケーションが中央集権的なウェブサイトに依存しないようにするために、スマートコントラクトとDAppインターフェースの間に効果的な相互運用性が必要です。

このEIPは、これらの問題を解決するために、スマートコントラクトへのリソースリクエストとレスポンスの受け取りを行うための標準的な方法を提供するものです。
これにより、DAppの分散化された性質が強化され、信頼性や検閲への脆弱性が軽減されることが期待されます。

# 仕様

## 名前解決 (Name Resolution)
名前解決メカニズムは、ユーザーが分散型アプリケーション（DApp）やスマートコントラクトにアクセスする際に、アドレスやリソースの名前を解決する仕組みです。
このEIPでは、名前解決メカニズムを提案するEIPが、このEIPを参照して、自身の提案するメカニズムを説明したり、クライアントにそのメカニズムのサポートを推奨したりできることを示しています。
また、クライアントが通常のDNSもサポートできることが明記されています。

## 関心の分離 (Separation of Concerns)

関心の分離は、アプリケーション全体の機能を適切な部分に分割することを指します。
この場合、アプリケーションロジック（バックエンド処理やスマートコントラクトのロジック）とフロントエンドロジック（ユーザーインターフェースやユーザー対話）を分離することが推奨されています。
これにより、コードのメンテナンスやスケーラビリティが向上し、変更の影響範囲が狭まります。

## コントラクトインターフェース (Contract Interface)

DAppのコントラクトは、スマートコントラクト間での相互運用性を確保するために、特定のインターフェースを実装する必要があります。
このインターフェースは、外部のアプリケーションやスマートコントラクトがDAppとやり取りするための契約書のようなものです。
このEIPでは、DAppのコントラクトが実装すべきインターフェースが定義されており、そのファイルを参照するように言及されています。
これにより、異なるコントラクト間での一貫性と互換性が確保されます。

## 実装者への注意 (Note to Implementers):

ガスコストはトランザクションの処理にかかるコストを指し、少ないガスで処理することが重要です。
`message/external-body`MIMEタイプを使用することで、スマートコントラクトが直接アクセスできないデータを参照することが可能です。
例えば、IPFS上に保存されたデータを指し示す際に有用です。
インターフェースや通信の効率を向上させるためのテクニックとして、以下の情報が提供されています。

```yaml
statusCode: 200
body: THIS IS NOT REALLY THE BODY!
headers:
  - key: Content-type
    value: message/external-body; access-type=URL; URL="ipfs://11148a173fd3e32c0fa78b90fe42d305f202244e2739"
```

このEIPは、名前解決やインターフェースの実装、データの効率的な取得などに関する標準的な手法を提供しており、スマートコントラクトとDAppの相互作用をより効果的にするためのガイドラインを示しています。

# 補足

読み取り専用のリクエストメソッドが選ばれたのは、全てのデータはパースされたDAppからコントラクトに送信されるべきだからです。

:::note info
分散型アプリケーション（DApp）では、スマートコントラクトとの相互作用が重要です。
このEIPでは、データの送信はすべてパースされたDAppからスマートコントラクトに行うべきだとされています。
つまり、スマートコントラクトへのリクエストは読み取り専用の操作に限定されます。
なぜなら、スマートコントラクトにデータを送信するためにトランザクションを提出する場合、コストがかかり、トランザクションがブロックにマイニングされるのを待つ必要があり、ユーザーエクスペリエンスが悪化する可能性があるからです。
:::

リクエストを送信するためにトランザクションを提出することはコストがかかり、トランザクションがマイニングされるのを待つ必要があり、ユーザーエクスペリエンスが悪化します。

:::note info
トランザクションを提出するためには、ガス料金が必要です。
このガス料金はトランザクションの処理コストをカバーするもので、DAppユーザーが支払う必要があります。
トランザクションを提出する場合、これらのガス料金を支払うだけでなく、トランザクションがブロックに含まれるまで待たなければなりません。
この待ち時間はユーザーエクスペリエンスを悪化させる可能性があります。
:::

複雑なフロントエンドロジックはスマートコントラクトに格納されるべきではなく、エンドユーザーのマシン上で実行する方がコストがかからず、効率的です。

:::note info
複雑なフロントエンドロジックは、スマートコントラクト内に格納されるべきではありません。
なぜなら、スマートコントラクト内にロジックを格納すると、スマートコントラクトのデプロイにかかるコストが高くなり、かつスマートコントラクトのロジックを変更するたびにデプロイが必要となります。
その代わりに、複雑なロジックはエンドユーザーのマシン上で実行されるべきであり、それによってコストを節約し、効率的な動作が可能となります。
:::

## 関心の分離

フロントエンドのコントラクトはバックエンドのスマートコントラクトとの対話について心配する必要はありません。
他のEIP（Ethereum Improvement Proposal）は、307 Temporary Redirectステータスコードと組み合わせて状態変更の操作を要求するために使用できます。

:::note info
他のEIPは、「**307 Temporary Redirect**」ステータスコードを使って、リダイレクトと組み合わせて状態変更の操作を要求するために使用できます。
これにより、リクエストが行うべき操作が指定され、必要な変更が実行される可能性があります。
:::

完全なHTTPリクエストを模倣する代わりに、非常に簡素化されたバージョンが選ばれました。

:::note info
DAppとスマートコントラクトの通信をシンプルにし、効率的な処理を実現するための選択です。
:::

特に関連性の高いHTTPメソッドは**GET**だけです。
クエリパラメータはリソース内にエンコードできます。
**GET**リクエストに対しては、リクエストヘッダはほとんど不要です。

:::note info
DAppの通信において、GETメソッドが特に関連性が高いです。
GETメソッドは情報の取得に適したメソッドであり、必要なデータをリソースから取得する際に適しています。
また、クエリパラメータはリソース内にエンコードできることで、リソース自体が必要な情報を持ち、効率的なデータの取得が可能となります。
:::

# 後方互換性

このEIPは、名前解決セクションでリストアップされているすべての標準と後方互換性があります。

# セキュリティ考慮事項

通常のURLへのアクセス時のセキュリティ考慮事項はここでも適用されます。
たとえば、`3XX`リダイレクトに従うことによるプライバシー漏洩の潜在的なリスクがあります。
これにより、EIPがなぜ特定の設計や仕様が採用されたのか、そしてその理由がどのように分散型アプリケーションの開発やセキュリティに影響を与えるかが理解できるかと思います。

# 参考実装

こちらに置いてありました。

https://github.com/ethereum/EIPs/blob/master/assets/eip-5219/IDecentralizedApp.sol

# 引用

Gavin John (@Pandapip1), "ERC-5219: Contract Resource Requests," Ethereum Improvement Proposals, no. 5219, July 2022. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-5219.

# 考察

Dappを作成するには、コントラクトの実装のみだけではなく、フロントエンドやバックエンドの実装も必要になってきます。
そのため、コントラクトとフロントエンド部分で相互運用性が保たれていたり、単一のアプリケーションを使用したり信頼する必要がないようにしたいという課題からの提案だとざっくり理解しました。
ただ、あまり使用する・したい場面が思い浮かばないため、もっとしっかり理解したい気持ちがあります。
ぜひ活用方法が思い浮かぶ人はコメントで教えていただきたいです🙇‍♂️

追記: 以下でなかなか激しい議論が行われていました。

https://ethereum-magicians.org/t/eip-5219-discussion-contract-resource-requests/9907

# 最後に

今回は「商品を購入したレシートをNFTのメタデータに書きこんで、ブロックチェーン上に書き込むことができる**ERC5570**」についてまとめてきました！
いかがだったでしょうか？

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

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