はじめに
初めまして。
CryptoGamesというブロックチェーンゲーム企業でエンジニアをしている cardene(かるでね) です!
スマートコントラクトを書いたり、フロントエンド・バックエンド・インフラと幅広く触れています。
代表的なゲームはクリプトスペルズというブロックチェーンゲームです。
今回は、HTTPスタイルのWeb3URLをEVM呼び出しメッセージに変換する仕組みを提案しているERC6860についてまとめていきます!
以下にまとめられているものを翻訳・要約・補足しながらまとめていきます。
他にも様々なEIPについてまとめています。
概要
この規格では、RFC3986をweb3://uniswap.eth/
のようなEVMメッセージに変換する仕組みを提案しています。
EVMMessage {
To: 0xaabbccddee.... // where uniswap.eth's address registered at ENS
Calldata: 0x
...
}
RFC3986は、Uniform Resource Identifier (URI)の構文に関する標準を定めたものです。
URIはインターネット上のリソースを識別するために使用されます。
主な内容
URIは5つの部分で構成されます。
-
スキーム (scheme)
- リソースへのアクセス方法を指定。
- 例
-
http
,https
,ftp
-
-
認証情報 (authority)
- ホスト名やユーザー情報を含む。
- 例
//user:pass@host:port
-
パス (path)
- リソースの位置を示す。
- 例
/path/to/resource
-
クエリ (query)
- リソースへの追加情報を提供。
- 例
?key1=value1&key2=value2
-
フラグメント (fragment)
- リソース内の特定の部分を指す。
- 例
#section1
スキームはアルファベットで始まり、アルファベット、数字、プラス(+
)、ドット(.
)、ハイフン(-
)を含むことができます。
また、特殊文字はエンコードする(例: スペースは%20
にエンコード。)必要があります。
相対URI(ベースURIからの相対パスで指定されるURI)やURIの正規化(URIを比較するために標準形式に変換するプロセス)などの特徴もあります。
具体例
https://example.com:8080/path/to/resource?query=123#section2
-
スキーム
https
-
認証情報
example.com:8080
-
パス
/path/to/resource
-
クエリ
query=123
-
フラグメント
section2
この規格は、ERC4804にに若干の変更を加えた提案になります。
ERC4804については以下の記事を参考にしてください。
動機
Web3のデータを読み取るとき、通常RPCノードやEtherscan、DappsなどのWeb2プロキシを介してブロックチェーンにアクセスする必要があります。
Web2ユーザーがWeb3コンテンツに直接アクセスすることは難しく、プロキシを介してアクセスすることがほとんどです。
この規格では、Web2ユーザーがプロキシを介さずに直接Web3コンテンツにアクセスできる方法を提供します。
特にオンチェーンにSVGやHTML、メタデータなどのコンテンツが保存されているときこの規格が役に立ちます。
SVGやHTMLなどのURIに互換性のある標準との相互運用性を可能にし、Web3コンテンツを既存のWeb2インフラストラクチャとシームレスに統合することができます。
仕様
この規格では、RFC2234というプロトコルやデータ形式の構文を正確に定義するAugmented Backus-Naur Form (ABNF)を使用しています。
RFC2234は、Augmented BNF for Syntax Specifications(ABNF)というデータ形式やプロトコルの構文を正確に記述するために使用される形式について定義しています。
基本情報
ABNFはネットワークプロトコルやデータ形式の構文を記述するための標準的な形式を提案しています。
基本構造
-
規則(Rule)
- ABNFは、名前付きの規則(ルール)を使って構文を記述します。
- 例
rule = definition
-
リテラル(Literal)
- 文字列や文字を直接表現します。
- 例
"text"
-
オルタネーション(Alternation)
- 複数の選択肢を示します。
- 例
rule1 / rule2
-
連接(Concatenation)
- シーケンスを示します。
- 例
rule1 rule2
記号の使用
-
コロン(=)
- 規則の定義を示す。
-
斜線(/)
- 選択肢の区切りを示す。
-
括弧(())
- グループ化を示す。
-
角括弧([])
- オプションを示す。
-
アスタリスク(*)
- 繰り返しを示す。
データ型
-
数字
- 数字を使って範囲や回数を指定します。
- 例
-
DIGIT = %x30-39
(0から9の数字)
-
-
文字
- 文字の範囲を指定します。
- 例
-
ALPHA = %x41-5A / %x61-7A
(AからZおよびaからz)
-
具体例
URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
hier-part = "//" authority path-abempty
この例では、URIの構文を記述しています。
-
URI
-
scheme
、hier-part
、query
、fragment
の組み合わせ。
-
-
scheme
- アルファベットで始まり、アルファベット、数字、
+
、-
、.
の組み合わせ。
- アルファベットで始まり、アルファベット、数字、
-
hier-part
-
authority
とpath-abempty
の組み合わせ。
-
Web3 URLは以下の形式を持つASCII文字列です。
web3URL = schema "://" [ userinfo "@" ] contractName [ ":" chainid ] pathQuery
-
schema
- スキーム部分は
"w3"
または"web3"
です。 - この部分はURLがWeb3 URLであることを示します。
- スキーム部分は
schema = "w3" / "web3"
-
userinfo
-
userinfo
はアドレスを表し、EVMコールメッセージの「from
」フィールドに相当します。 - 指定されていない場合、プロトコルは送信者アドレスとして
0x0
を使用します。
-
userinfo = address
-
contractName
- コントラクト名を指定し、EVMコールメッセージの「
to
」フィールドに相当します。 - これはアドレスまたはドメイン名です。
- ドメイン名の場合、それは名前解決サービス(例:Ethereum Name Service)を通じてアドレスに解決されます。
- コントラクト名を指定し、EVMコールメッセージの「
contractName = address / domainName
address = "0x" 20( HEXDIG HEXDIG )
domainName = *( unreserved / pct-encoded / sub-delims )
-
chainid
- チェーンIDを指定し、どのブロックチェーン上で
contractName
を解決してメッセージを送信するかを決定します。 - 指定されていない場合、プロトコルは名前サービスプロバイダーの主要チェーン(例:Ethereumの場合は
1
)を使用します。
- チェーンIDを指定し、どのブロックチェーン上で
chainid = %x31-39 *DIGIT
-
pathQuery
- パスとオプションのクエリからなり、手動モード(manual mode)または自動モード(auto mode)によって構造が異なります。
pathQuery = mPathQuery / aPathQuery
相対URL
Web3 URLは相対URLをサポートしており、Resolveモードによってサポートの方法が異なります。
web3UrlRef = web3URL / relativeWeb3URL
relativeWeb3URL = relPathQuery
relPathQuery = relMPathQuery / relAPathQuery
具体例
例えば、以下のWeb3 URLを考えます。
web3://0x1234567890abcdef1234567890abcdef12345678@0xabcdef1234567890abcdef1234567890abcdef12:1/path/to/resource?query=param
-
schema
web3
-
userinfo
-
0x1234567890abcdef1234567890abcdef12345678
(EVMコールメッセージの送信者)
-
-
contractName
-
0xabcdef1234567890abcdef1234567890abcdef12
(スマートコントラクトのアドレス)
-
-
chainid
-
1
(Ethereumメインネット)
-
-
pathQuery
-
/path/to/resource?query=param
(リソースのパスとクエリ)
-
Resolveモード
Resolveモードには、手動モード(manual mode)と自動モード(auto mode)の2つがあります。
Resolveモードの確認方法
プロトコルは、「to
o」アドレスのresolveMode
メソッドを呼び出すことでResolveモードを確認します。
このメソッドのSolidity署名は以下の通りです。
function resolveMode() external returns (bytes32);
サポートされているResolveモード
手動モード(manual mode)
resolveMode
の戻り値が以下の値と一致する場合に手動モードが使用されます。
0x6d616e75616c0000000000000000000000000000000000000000000000000000
これは、"manual"
をbytes32形式にエンコードしたものです。
自動モード(auto mode)
resolveMode
の戻り値が以下のいずれかと一致する場合に自動モードが使用されます。
0x6175746f00000000000000000000000000000000000000000000000000000000
これは、"auto"
をbytes32形式にエンコードしたものです。
または、戻り値が以下の場合も自動モードが使用されます。
0x0000000000000000000000000000000000000000000000000000000000000000
さらに、resolveMode
メソッドの呼び出しがエラーを投げる(メソッドが実装されていないか、メソッド内でエラーが発生する)場合も自動モードが使用されます。
その他のモード
上記に該当しない戻り値を返した場合、プロトコルはリクエストを失敗させ、「unsupported resolve mode」というエラーを返します。
手動モード
手動モードでは、mPathQuery
として指定された生のデータがメッセージのコールデータとして直接使用されます。
手動モードの構造
mPathQuery
手動モードのmPathQuery
は以下のように定義されます。
mPathQuery = mPath [ "?" mQuery ]
mPath
mPath
はmPathAbempty
で、スラッシュ/
で始まるか空である必要があります。
mPath = mPathAbempty ; begins with "/" or is empty
mPathAbempty
は、セグメントの繰り返しとオプションのファイル拡張子からなります。
mPathAbempty = [ *( "/" segment ) "/" segment [ "." fileExtension ] ]
segment = *pchar ; as in RFC 3986
fileExtension = 1*( ALPHA / DIGIT )
segment
は任意の文字列で、fileExtension
はアルファベットまたは数字の繰り返しです。
mQuery
mQuery
は、RFC3986に準拠した任意の文字列です。
mQuery = *( pchar / "/" / "?" ) ; as in RFC 3986
手動モードの動作
mPathQuery
が空の場合、送信されるコールデータは/
(0x2f)になります。
返されたメッセージデータはABIエンコードされたバイト列として扱われ、デコードされたバイト列がフロントエンドに返されます。
フロントエンドに返されるMIMEタイプはデフォルトでtext/html
ですが、ファイル拡張子が存在する場合、そのファイル拡張子からMIMEタイプが推定されます。
相対URLのサポート
手動モードでは、HTTP URLに似た相対URLもサポートされています。
relMPathQuery
相対URLの構造は以下の通りです。
relMPathQuery = relMPath [ "?" mQuery ]
relMPath
relMPath
は、絶対パスmPathAbsolute
、非スキームパスmPathNoscheme
、空のパスmPathEmpty
から構成されます。
relMPath = mPathAbsolute ; begins with "/" but not "//"
/ mPathNoscheme ; begins with a non-colon segment
/ mPathEmpty ; zero characters
mPathAbsolute
はスラッシュで始まり、オプションのファイル拡張子を持つことができます。
mPathAbsolute = "/" [ segmentNz *( "/" segment ) ] [ "." fileExtension ]
mPathNoscheme
はコロン(:
)を含まないセグメントで始まり、オプションのファイル拡張子を持つことができます。
mPathNoscheme = segmentNzNc *( "/" segment ) [ "." fileExtension ]
segmentNzNc = 1*( unreserved / pct-encoded / sub-delims / "@" )
mPathEmpty
は空の文字列です。
mPathEmpty = 0<pchar>
自動モード
このセクションは、Web3 URLの自動モード(Auto Mode)について説明しています。自動モードでは、関数の呼び出し方法と引数の指定方法が定義されています。これにより、ユーザーは特定のスマートコントラクトの関数を呼び出し、結果を取得することができます。
自動モードの構造
aPathQuery
自動モードのaPathQuery
は、以下のように定義されます。
aPathQuery = aPath [ "?" aQuery ]
aPath
aPath
は、関数メソッドと引数を含むオプションのパスです。
空またはスラッシュ/
だけの場合、ターゲットコントラクトは空のコールデータで呼び出されます。
それ以外の場合、標準のSolidityコントラクトABIが使用されます。
aPath = [ "/" [ method *( "/" argument ) ] ]
method
method
は、呼び出す関数の名前を示す文字列です。
method = ( ALPHA / "$" / "_" ) *( ALPHA / DIGIT / "$" / "_" )
argument
argument
は、関数メソッドの引数を示します。
argument = boolArg / uintArg / intArg / addressArg / bytesArg / stringArg
-
boolArg
- 真偽値を示す引数。
boolArg = [ "bool!" ] ( "true" / "false" )
-
uintArg
- 符号なし整数を示す引数。
uintArg = [ "uint" [ intSizes ] "!" ] 1*DIGIT
-
intArg
- 符号付き整数を示す引数。
intArg = "int" [ intSizes ] "!" 1*DIGIT
-
addressArg
- アドレスを示す引数。
addressArg = [ "address!" ] ( address / domainName )
-
bytesArg
- バイト列を示す引数。
bytesArg = [ "bytes!" ] bytes / "bytes1!0x" 1( HEXDIG HEXDIG ) / ... / "bytes32!0x" 32( HEXDIG HEXDIG )
-
stringArg
- 文字列を示す引数。
stringArg = "string!" *pchar [ "." fileExtension ]
自動型検出
型が指定されていない場合、以下の規則で自動的に型が検出されます。
- 数字の場合
uint256
- 32バイトのデータの場合
bytes32
- 20バイトのデータの場合
address
- それ以外のバイトデータの場合
bytes
-
true
またはfalse
の場合bool
- 上記以外の場合
-
address
としてドメイン名を解釈し、解決できなければエラーを返します。
-
aQuery
クエリ部分は、返されるデータの形式を指定します。
aQuery = attribute *( "&" attribute )
-
attribute
-
returns
属性は、返されるデータの形式を指定します。
-
attribute = attrName "=" attrValue
attrName = "returns" / "returnTypes"
attrValue = [ "(" [ retTypes ] ")" ]
retTypes = retType *( "," retType )
retType = retRawType *( "[" [ %x31-39 *DIGIT ] "]" )
retRawType = "(" retTypes ")" / retBaseType
retBaseType = "bool" / "uint" [ intSizes ] / "int" [ intSize ] / "address" / "bytes" [ bytesSizes ] / "string"
返されるデータ
returns
属性が未定義または空の場合、返されるメッセージデータはABIエンコードされたバイト列として扱われます。
returns
属性が()
の場合、返されるデータは生のバイト列としてJSON配列にエンコードされます。
その他の場合、returns
属性のデータ型に従ってABIデコードされ、JSON形式でエンコードされます。
相対URLのサポート
自動モードでは、相対URLは現在のコントラクトに対して相対的に解決され、自己参照、/
パス、または完全なメソッドと引数を参照できます。
例
Example 1a
# 手動モード
web3://w3url.eth/
- ENSを使って
w3url.eth
のアドレスを取得します(チェーンIDは1
、つまりMainnet)。 -
resolveMode()
メソッドを呼び出して、0xDD473FAE
をcalldata
として送信し、戻り値がmanual
であることを確認します。 - コントラクトに
To
アドレスを指定し、calldata
として0x2F
(スラッシュ/
)を送信します。 - 返されたデータはABIエンコードされたバイトとして処理され、フロントエンドに返されます。
- MIMEタイプはデフォルトで
text/html
です。
- MIMEタイプはデフォルトで
Example 1b
# 自動モード
web3://w3url.eth/
- ENSを使って
w3url.eth
のアドレスを取得します(チェーンIDは1
、つまりMainnet)。 -
resolveMode()
メソッドを呼び出して、0xDD473FAE
をcalldata
として送信し、戻り値が空であることを確認します(自動モード)。 - コントラクトに
To
アドレスを指定し、空のcalldata
で呼び出します。 - 返されたデータはABIエンコードされたバイトとして処理され、フロントエンドに返されます。
- MIMEタイプは未定義です。
Example 2
# 自動モード
web3://cyberbrokers-meta.eth/renderBroker/9999
- ENSを使って
cyberbrokers-meta.eth
のアドレスを取得します(チェーンIDは1
、つまりMainnet)。 -
resolveMode()
メソッドを呼び出して、0xDD473FAE
をcalldata
として送信し、戻り値が空であることを確認します(自動モード)。 - コントラクトに
To
アドレスを指定し、calldata
として0x
+keccak("renderBroker(uint256)")[0:4]
+abi.encode(uint256(9999))
を送信します。 - 返されたデータはABIエンコードされたバイトとして処理され、フロントエンドに返されます。
- MIMEタイプは未定義です。
Example 3
# 手動モード
web3://vitalikblog.eth:5/
- ENSを使って
vitalikblog.eth
のアドレスを取得します(チェーンIDは5
、つまりGoerli)。 -
resolveMode()
メソッドを呼び出して、手動モードであることを確認します。 - コントラクトに
To
アドレスを指定し、calldata
として0x2F
(スラッシュ/
)を送信します。 - 返されたデータはABIエンコードされたバイトとして処理され、フロントエンドに返されます。
- MIMEタイプは
text/html
です。
- MIMEタイプは
Example 4
# 手動モード
web3://0xe4ba0e245436b737468c206ab5c8f4950597ab7f:42170/
-
resolveMode()
メソッドを呼び出して、手動モードであることを確認します。 - コントラクトに
To
アドレス(0xe4ba0e245436b737468c206ab5c8f4950597ab7f
)を指定し、calldata
として0x2F
(スラッシュ/
)を送信します(チェーンIDは42170
、つまりArbitrum Nova)。 - 返されたデータはABIエンコードされたバイトとして処理され、フロントエンドに返されます。
- MIMEタイプは
text/html
です。
- MIMEタイプは
Example 5
# 自動モード
web3://0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48/balanceOf/vitalik.eth?returns=(uint256)
- ENSを使って
vitalik.eth
のアドレスを取得します(チェーンIDは1
、つまりMainnet)。 - コントラクトの
balanceOf(address)
メソッドをvitalik.eth
のアドレスで呼び出します。 - 返されたデータはABIエンコードされた
uint256
型として処理され、JSON形式でフロントエンドに返されます。MIMEタイプはapplication/json
です。
Example 6
# 自動モード
web3://0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48/balanceOf/vitalik.eth?returns=()
- ENSを使って
vitalik.eth
のアドレスを取得します(チェーンIDは1
、つまりMainnet)。 - コントラクトの
balanceOf(address)
メソッドをvitalik.eth
のアドレスで呼び出します。 - 返されたデータは生のバイト列として処理され、JSON形式でフロントエンドに返されます。
- MIMEタイプは
application/json
です。
- MIMEタイプは
Web3URLの完全なABNF
Web3URLの完全なABNFを開く
web3URL = schema "://" [ userinfo "@" ] contractName [ ":" chainid ] pathQuery
schema = "w3" / "web3"
userinfo = address
contractName = address
/ domainName
chainid = %x31-39 *DIGIT
pathQuery = mPathQuery ; path+query for manual mode
/ aPathQuery ; path+query for auto mode
web3UrlRef = web3URL
/ relativeWeb3URL
relativeWeb3URL = relPathQuery
relPathQuery = relMPathQuery ; Relative URL path+query for manual mode
/ relAPathQuery ; Relative URL path+query for auto mode
mPathQuery = mPath [ "?" mQuery ]
mPath = mPathAbempty ; begins with "/" or is empty
relMPathQuery = relMPath [ "?" mQuery ]
relMPath = mPathAbsolute ; begins with "/" but not "//"
/ mPathNoscheme ; begins with a non-colon segment
/ mPathEmpty ; zero characters
mPathAbempty = [ *( "/" segment ) "/" segment [ "." fileExtension ] ]
mPathAbsolute = "/" [ segmentNz *( "/" segment ) ] [ "." fileExtension ]
mPathNoscheme = segmentNzNc *( "/" segment ) [ "." fileExtension ]
mPathEmpty = 0<pchar>
segment = *pchar ; as in RFC 3986
segmentNz = 1*pchar ; as in RFC 3986
segmentNzNc = 1*( unreserved / pct-encoded / sub-delims / "@" )
; as in RFC 3986: non-zero-length segment without any colon ":"
mQuery = *( pchar / "/" / "?" ) ; as in RFC 3986
aPathQuery = aPath [ "?" aQuery ]
aPath = [ "/" [ method *( "/" argument ) ] ]
relAPathQuery = aPath [ "?" aQuery ]
method = ( ALPHA / "$" / "_" ) *( ALPHA / DIGIT / "$" / "_" )
argument = boolArg
/ uintArg
/ intArg
/ addressArg
/ bytesArg
/ stringArg
boolArg = [ "bool!" ] ( "true" / "false" )
uintArg = [ "uint" [ intSizes ] "!" ] 1*DIGIT
intArg = "int" [ intSizes ] "!" 1*DIGIT
intSizes = "8" / "16" / "24" / "32" / "40" / "48" / "56" / "64" / "72" / "80" / "88" / "96" / "104" / "112" / "120" / "128" / "136" / "144" / "152" / "160" / "168" / "176" / "184" / "192" / "200" / "208" / "216" / "224" / "232" / "240" / "248" / "256"
addressArg = [ "address!" ] ( address / domainName )
bytesArg = [ "bytes!" ] bytes
/ "bytes1!0x" 1( HEXDIG HEXDIG )
/ "bytes2!0x" 2( HEXDIG HEXDIG )
/ "bytes3!0x" 3( HEXDIG HEXDIG )
/ "bytes4!0x" 4( HEXDIG HEXDIG )
/ "bytes5!0x" 5( HEXDIG HEXDIG )
/ "bytes6!0x" 6( HEXDIG HEXDIG )
/ "bytes7!0x" 7( HEXDIG HEXDIG )
/ "bytes8!0x" 8( HEXDIG HEXDIG )
/ "bytes9!0x" 9( HEXDIG HEXDIG )
/ "bytes10!0x" 10( HEXDIG HEXDIG )
/ "bytes11!0x" 11( HEXDIG HEXDIG )
/ "bytes12!0x" 12( HEXDIG HEXDIG )
/ "bytes13!0x" 13( HEXDIG HEXDIG )
/ "bytes14!0x" 14( HEXDIG HEXDIG )
/ "bytes15!0x" 15( HEXDIG HEXDIG )
/ "bytes16!0x" 16( HEXDIG HEXDIG )
/ "bytes17!0x" 17( HEXDIG HEXDIG )
/ "bytes18!0x" 18( HEXDIG HEXDIG )
/ "bytes19!0x" 19( HEXDIG HEXDIG )
/ "bytes20!0x" 20( HEXDIG HEXDIG )
/ "bytes21!0x" 21( HEXDIG HEXDIG )
/ "bytes22!0x" 22( HEXDIG HEXDIG )
/ "bytes23!0x" 23( HEXDIG HEXDIG )
/ "bytes24!0x" 24( HEXDIG HEXDIG )
/ "bytes25!0x" 25( HEXDIG HEXDIG )
/ "bytes26!0x" 26( HEXDIG HEXDIG )
/ "bytes27!0x" 27( HEXDIG HEXDIG )
/ "bytes28!0x" 28( HEXDIG HEXDIG )
/ "bytes29!0x" 29( HEXDIG HEXDIG )
/ "bytes30!0x" 30( HEXDIG HEXDIG )
/ "bytes31!0x" 31( HEXDIG HEXDIG )
/ "bytes32!0x" 32( HEXDIG HEXDIG )
stringArg = "string!" *pchar [ "." fileExtension ]
aQuery = attribute *( "&" attribute )
attribute = attrName "=" attrValue
attrName = "returns"
/ "returnTypes"
attrValue = [ "(" [ retTypes ] ")" ]
retTypes = retType *( "," retType )
retType = retRawType *( "[" [ %x31-39 *DIGIT ] "]" )
retRawType = "(" retTypes ")"
/ retBaseType
retBaseType = "bool" / "uint" [ intSizes ] / "int" [ intSize ] / "address" / "bytes" [ bytesSizes ] / "string"
bytesSizes = %x31-39 ; 1-9
/ ( "1" / "2" ) DIGIT ; 10-29
/ "31" / "32" ; 31-32
domainName = *( unreserved / pct-encoded / sub-delims ) ; As in RFC 3986
fileExtension = 1*( ALPHA / DIGIT )
address = "0x" 20( HEXDIG HEXDIG )
bytes = "0x" *( HEXDIG HEXDIG )
pchar = unreserved / pct-encoded / sub-delims / ":" / "@" ; As in RFC 3986
pct-encoded = "%" HEXDIG HEXDIG ; As in RFC 3986
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" ; As in RFC 3986
sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
/ "*" / "+" / "," / ";" / "=" ; As in RFC 3986
ERC4804からの変更点
修正点 (Corrections)
-
手動モード (Manual mode)
- ERC4804ではパスとクエリはそのまま使用されていましたが、この規格ではMIMEタイプを決定するために使用されています。
-
自動モード (Auto mode)
-
ERC4804ではクエリに
returns
属性がない場合、返されるデータはABIエンコードされたbytes32
として扱われていましたが、この規格では実際には返されるデータはABIエンコードされたバイト列として扱われます。
-
ERC4804ではクエリに
明確化 (Clarifications)
-
正式仕様 (Formal specification)
- この規格ではURL形式のABNF定義が追加されています。
-
Resolveモード (Resolve mode)
- この規格ではResolveモードがどのように決定されるかの詳細が示されています。
-
手動モード (Manual mode)
- URIパーセントエンコーディングの扱い、返されるデータ、MIMEタイプの決定方法についての詳細が示されています。
-
自動モード (Auto mode)
- 引数の値のエンコード方法や、
returns
値の形式と取り扱いについての詳細が示されています。
- 引数の値のエンコード方法や、
修正点 (Modifications)
-
プロトコル名 (Protocol name)
-
ERC4804では
ethereum-web3://
やeth-web3://
が定義されていましたが、この規格では削除されています。
-
ERC4804では
-
自動モード (Auto mode)
-
対応する型
-
ERC4804では
uint256
、bytes32
、address
、bytes
、string
のみをサポートしていましたが、この規格ではこれに加えさらに多くの型がサポートされています。
-
ERC4804では
- 返される整数のエンコード
-
ERC4804では整数を文字列としてエンコードしていましたが、この規格ではEthereum JSON RPC仕様に従い、整数を
0x
で始まる16進数文字列としてエンコードしています。
-
対応する型
補足
この提案の目的は、Ethereumに対して分散型プレゼンテーションレイヤーを追加することです。
このレイヤーを使用することで、人間が読みやすいURLを使ってオンチェーンでHTML/CSS/JPG/PNG/SVGなどのウェブコンテンツをレンダリングできるようにし、EVM(Ethereum Virtual Machine)を分散型のバックエンドとして活用できます。
主な原則
人間が読みやすい
Web3 URLは、Web2 URL(例:http://
)と同様に人間にとって容易に認識できるものである必要があります。
そのため、アドレスの代わりに名前サービスからの名前を使用することで、読みやすさを向上させます。
また、16進数のcalldata
の代わりに、人間が読みやすいメソッドと引数を使用してcalldata
に変換します。
HTTP-URL標準との最大限の互換性
Web3 URLは、HTTP-URL標準と互換性を持つべきで、相対パス、クエリ、フラグメント、パーセントエンコーディングなどが含まれます。
これにより、既存のHTTP-URLのサポート(例:ブラウザによるサポート)を最小限の変更でWeb3 URLに拡張できます。
また、既存のWeb2ユーザーがこの標準についての追加知識を最小限に抑えてWeb3に移行することが容易になります。
シンプル
引数に明示的な型を指定する代わりに、address
、bytes32
、uint256
などの引数の型を自動的に検出しています。
これにより、URLの長さを最小限に抑えて混乱を避けることができます。
必要に応じて、明示的な型もサポートされています。
柔軟
コントラクトはエンコーディングルールをオーバーライドできるため、ユーザーが特定したい実際のWebリソースをコントラクトが細かく制御できるようにします。
引用
Qi Zhou (@qizhou), Chao Pi (@pichaoqkc), Sam Wilson (@SamWilsn), Nicolas Deschildre (@nand2), "ERC-6860: Web3 URL to EVM Call Message Translation [DRAFT]," Ethereum Improvement Proposals, no. 6860, September 2023. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-6860.
最後に
今回は「HTTPスタイルのWeb3URLをEVM呼び出しメッセージに変換する仕組みを提案しているERC6860」についてまとめてきました!
いかがだったでしょうか?
質問などがある方は以下のTwitterのDMなどからお気軽に質問してください!
他の媒体でも情報発信しているのでぜひ他も見ていってください!