# [ERC4804] HTTP形式のWeb3 URLからコントラクトを呼び出すことができる仕組みを理解しよう！

> この標準は、インターネット上のアドレスを示すURI（例: web3://uniswap.eth/）をイーサリアムブロックチェーンで使える形に変換するものです。具体的には、「EVMMessage」というメッセージ形式に変換します。

- URL: https://cardene.dev/articles/837931ce60ca844aee13
- 公開日: 2023-12-27
- 更新日: 2023-12-27
- トピック: Blockchain
- タグ: ethereum, solidity, smartcontract, ブロックチェーン

## はじめに

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

https://cryptogames.co.jp/

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

https://cryptospells.jp/

今回は、HTTP形式のWeb3 URLからEVMコールメッセージへの変換の仕組みを提案している規格である**ERC4804**についてまとめていきます！

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

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

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

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

## 概要

この標準は、インターネット上のアドレスを示すURI（例: `web3://uniswap.eth/`）をイーサリアムブロックチェーンで使える形に変換するものです。
具体的には、「**EVMMessage**」というメッセージ形式に変換します。
この変換を通じて、人々は通常のウェブアドレスのように見えるURIを使って、イーサリアム上の特定のコントラクトと直接やり取りできるようになります。

この「**EVMMessage**」には主に2つの部分があります。
「**To**」には、ENSを通じて`uniswap.eth`という名前が指し示す具体的なコントラクトアドレスが入ります。
これは、あなたがそのコントラクトとやり取りしたいときに、どこにメッセージを送ればいいのかを示しています。
次に、「**Calldata**」は、そのコントラクトに送る具体的な命令やデータを含んでいます。

:::message
この標準は、イーサリアムブロックチェーン上で実際に動作するコントラクトとやり取りするための技術的なメッセージを、人が読みやすいウェブアドレスに変換する提案です。
これにより、複雑なブロックチェーンのアドレスや命令を覚える必要なく、ユーザーは簡単にコントラクトとやり取りできるようになります。
:::

## 動機

Web3では、誰でもブロックチェーンという複雑な技術のデータにアクセスできるように、その仲介をするサービスが必要です。
これは、ウェブサイトやEtherscanのようなサービスが、複雑なブロックチェーンの情報を多くのユーザーが理解しやすい形に変換しています。
しかし、これらのサービスはユーザーのコントロール外にあり、信頼性や透明性の問題が生じることがあります。

ここで紹介されている新しい標準は、Web2のユーザーがブロックチェーンのデータ、特にSVGやHTMLなどのオンチェーンWebコンテンツに、直接かつ簡単にアクセスできるようにするためのものです。
この標準を使うと、ユーザーは仲介者なしで、自分自身でコンテンツにアクセスし、**ERC20**や**ERC721**などのコントラクトと直接やり取りすることができます。
これは、Web3の世界をもっと使いやすくし、より多くの人にとってアクセスしやすいものにすることを目的としています。

また、この標準は既にURIと互換性のある他の技術、例えばウェブページを構成するSVGやHTMLとも連携できます。
これにより、既存のウェブ技術とブロックチェーン技術の間のギャップを埋め、Web3の世界への移行をよりスムーズにすることが期待されています。

## 仕様

Web3 URLは、イーサリアムのブロックチェーン上で特定のコントラクトや操作に簡単にアクセスできるようにするアドレスです。

```
web3URL = web3Schema [userinfo "@"] contractName [":" chainid] path ["?" query]
web3Schema = [ "ethereum-web3://" | "eth-web3://" | "web3://" ]
contractName = address | [name "." [ subDomain0 "." ... ]] nsProviderSuffix
path = ["/" method ["/" argument_0 ["/" argument_1 ... ]]]
argument = [type "!"] value
query = "attribute_1=value_1 [ "&" attribute_2=value_2 ... ]
attribute = "returns" | "returnTypes" | other_attribute
```

URLは以下のように構成されます。

- `web3Schema`
    - これはURLの始まりを示し、「`ethereum-web3://`」、「`eth-web3://`」、「`web3://`」のいずれかです。
    - これにより、ブラウザやアプリがWeb3の内容を認識し、適切に処理できるようになります。
- `userinfo`
    - これはどのユーザーが操作を実行しているかを示します。
    - これは通常、ウォレットアドレスのような形で指定され、トランザクションの「**送信者**」として機能します。
    - 指定されていない場合は、デフォルトのアドレスが使用されます。
- `contractName`
    - これは操作の対象となるコントラクトを指定し、EVMコールメッセージの「To」フィールドに相当します。
    - これは直接のアドレス（`0x`に続く`20`バイトのデータのヘックス形式のアドレス）またはENSなどの名前サービスを通じて解決される名前（例：`uniswap.eth`）のどちらでも指定可能です。
    - ENSなどの名前サービスを使用する場合は、そのプロバイダの接尾語（例：`eth`）も含まれます。
- `chainid`
    - どのブロックチェーン（チェーン）上でこの操作を実行するかを指定します。
    - 特定のチェーンが指定されていない場合、名前サービスプロバイダのチェーン、またはデフォルトでチェーンID `1`（イーサリアムメインネット）が使用されます。
- `path`
    - コントラクト内の特定のメソッドやその引数を指定します。
    - 例えば、「`/transfer/0xab.../100`」は`transfer`メソッドを呼び出し、特定のアドレスに特定の量を送ることを意味します。
- `query`
    - これはオプションで、返り値の型などの追加情報を指定するために使われます。
    - これは属性と値のペアで構成され、"&"で区切られます。

このURL形式を使用すると、ユーザーはブラウザやアプリから直接、特定の**ERC20**や**ERC721**コントラクトとやり取りしたり、特定の操作を実行したりできるようになります。
これにより、Web3の世界がよりアクセスしやすく、直感的になります。

### Resolve Mode

このプロトコルは、ブロックチェーン上のコントラクトとどのようにやり取りするかを決定するために、「**To**」アドレスと`chainid`を使ってコントラクトの`resolveMode`メソッドを呼び出します。
ここでいう`resolveMode`メソッドとは、指定されたコマンドやデータをコントラクトがどのように理解し処理するかを実行します。
現在、プロトコルは「**マニュアルモード**」と「**オートモード**」という2つのモードをサポートしています。

#### マニュアルモード
このモードでは、送られたコマンド（`path`）やデータ（`query`）に対する解釈は行わず、そのままコントラクトの`calldata`（コントラクトに送るデータ）として使われます。
これは、ユーザーが正確な`calldata`を知っていて、その通りにコントラクトに伝えたいときに便利です。

#### オートモード
これはデフォルトのモードで、より自動的にコントラクトの`calldata`を生成します。
もし`path`が空なら、空の`calldata`でコントラクトを呼び出します。
そうでなければ、標準のSolidityコントラクトABIに従って`calldata`を生成します。
これには、呼び出すメソッド名（`method`）や引数（`argument_i`）が含まれ、引数の型が指定されていればその型に合わせて値が変換されます。
型が指定されていない場合は、値の形式に基づいて自動的に型が判断されます。

さらに、`returns`属性を使って、コントラクトからの戻り値の形式を指定することもできます。
これにより、返されるデータをJSON形式で読みやすくするか、生のバイトとして取得するかを選べます。
これは、特定の情報を得たいときや、返されるデータをどのように扱いたいかに応じて役立ちます。

:::message
このプロトコルは、ユーザーがブロックチェーン上の**ERC20**や**ERC721**などのコントラクトとやり取りする際に、より柔軟かつ効率的にコミュニケーションを行えるようにするための方法を提供しています。
:::

### 実装例

Web3 URLプロトコルを使ってブロックチェーン上の特定のコントラクトや操作にアクセスする方法を、具体例を通して説明します。

#### `web3://w3url.eth/`
これは、イーサリアムメインネット（`chainid 1`）上のENSを通じて「`w3url.eth`」という名前のコントラクトアドレスを探し出し、そのアドレスに特定のデータ（`Calldata = "0x2F"`）を送ります。
これは、単純なコントラクト呼び出しを行う基本的な例です。

#### `web3://cyberbrokers-meta.eth/renderBroker/9999`
これは、`cyberbrokers-meta.eth`というコントラクトに対して、特定のメソッド（`renderBroker`）を特定のパラメータ（`9999`）を渡して呼び出します。
これにより、コントラクトは特定の操作を実行します。

#### `web3://vitalikblog.eth:5/`
このURLはGoerliテストネット（`chainid 5`）上の「`vitalikblog.eth`」というアドレスを探し出し、そこにデータを送ります。
これは、メインネット以外のチェーンにアクセスする時に使用します。

#### `web3://0xe4ba0e245436b737468c206ab5c8f4950597ab7f:42170/`
これは直接コントラクトのアドレス（`0xe4ba...7ab7f`）を指定し、Arbitrum Nova（`chainid 4217`0）でそのアドレスにメッセージを送ります。
名前解決を必要とせず、直接アドレスにアクセスします。

#### `web3://0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48/balanceOf/vitalik.eth?returns=(uint256)`
これは、特定の**ERC20**コントラクト（`0xA0b8...6eB48`）の`balanceOf`メソッドを呼び出し、`vitalik.eth`というアドレスのトークン残高を問い合わせます。
返されるデータは数値（`uint256`）として解析されます。

#### `web3://0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48/balanceOf/vitalik.eth?returns=()`
これも同様に`balanceOf`メソッドを呼び出しますが、返されるデータは生のバイト形式（`raw bytes`）として解析されます。

これらの例から分かるように、Web3 URLプロトコルは、異なるチェーン、コントラクト、メソッド、引数にアクセスし、ブロックチェーン上で特定のアクションを実行するための柔軟で強力な方法を提供します。

## 補足

この提案は、イーサリアムに新しい機能を追加し、HTMLやSVGなどのウェブコンテンツをブロックチェーン上で直接表示できるようにすることを目指しています。
これにより、EVM（イーサリアム仮想マシン）が分散型のバックエンドサービスとして機能し、より使いやすいインターネット体験を提供します。
この標準の設計は以下の4つの主要な原則に基づいています。

### 人間が読める
Web3 URLは、人間が普段使っているWeb2のURLのように簡単に読み取り可能であるべきです。
より良い可読性のために、複雑なアドレスの代わりに名前サービスからの名前を使用し、16進数の`calldata`の代わりに、人間が読める形式のメソッドと引数を用いて、これらを`calldata`に変換します。

### HTTP-URL標準との最大限の互換性
Web3 URLは、相対パスやクエリなどHTTP-URL標準と互換性があることで、既存のウェブブラウザやサービスが最小限の変更でWeb3に対応できるようにします。
これにより、既存のWeb2ユーザーも簡単にWeb3へ移行できます。

### シンプル
引数の型を明示的に指定する代わりに、アドレスや`uint256`などの引数の型を自動的に検出します。
これにより、URLが短くシンプルになり、混乱を減らすことができます。
明示的な型指定もサポートしており、必要に応じて混乱を解消できます。

### 柔軟性
コントラクトはエンコーディングルールをカスタマイズできるため、ユーザーが求める実際のWebリソースを正確に理解し、適切に反応できます。

## 引用

Qi Zhou (@qizhou), Chao Pi (@pichaoqkc), Sam Wilson (@SamWilsn), "ERC-4804: Web3 URL to EVM Call Message Translation," Ethereum Improvement Proposals, no. 4804, February 2022. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-4804.

## 最後に

今回は「HTTP形式のWeb3 URLからEVMコールメッセージへの変換の仕組みを提案している規格である**ERC4804**」についてまとめてきました！
いかがだったでしょうか？

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