ERC-4804: Web3 URL 到 EVM 调用消息的转换
将 HTTP 风格的 Web3 URL 转换为 EVM 调用消息
Authors | Qi Zhou (@qizhou), Chao Pi (@pichaoqkc), Sam Wilson (@SamWilsn) |
---|---|
Created | 2022-02-14 |
Requires | EIP-137 |
摘要
本标准将类似 web3://uniswap.eth/
的 RFC 2396 URI 转换为 EVM 消息,例如:
EVMMessage {
To: 0xaabbccddee.... // 其中 uniswap.eth 的地址已在 ENS 注册
Calldata: 0x
...
}
动机
目前,从 Web3 读取数据通常依赖于 Web2 代理到 Web3 区块链的转换。这种转换主要由 dApp 网站/节点服务提供商/etherscan 等代理完成,这些代理不受用户的控制。这里的标准旨在为 Web2 用户提供一种直接访问 Web3 内容的简单方法,特别是链上 Web 内容,如 SVG/HTML。此外,本标准还能够与其他已与 URI 兼容的标准(如 SVG/HTML)实现互操作性。
规范
本规范仅定义只读(即 Solidity 的 view
函数)语义。状态修改函数可以定义为未来的扩展。
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
其中
- web3Schema 表示 URL 的模式,简写为
web3://
或w3://
。 - userinfo 表示哪个用户正在调用 EVM,即 EVM 调用消息中的 “From” 字段。如果未指定,该协议将使用 0x0 作为发送者地址。
- contractName 表示要调用的合约,即 EVM 调用消息中的 “To” 字段。如果 contractName 是一个 address,即 0x + 20-byte-data hex,那么 “To” 将是该地址。否则,该名称来自名称服务。在第二种情况下,nsProviderSuffix 将是来自名称服务提供商的后缀,例如 “eth” 等。将名称从名称服务转换为地址的方式将在后续的 EIP 中讨论。
- chainid 表示解析 contractName 和调用消息的链。如果未指定,该协议将使用与名称服务提供商相同的链,例如,eth 使用 1。如果没有可用的名称服务提供商,则默认的 chainid 为 1。
- query 是一个可选组件,包含一系列由 “&” 分隔的属性-值对。
解析模式
一旦确定了 “To” 地址和 chainid,协议将通过调用 “resolveMode” 方法来检查合约的解析模式。该协议目前支持两种解析模式:
手动模式
手动模式不会对 path 和 query 进行任何解释,而是直接将 path [ “?” query ] 作为消息的 calldata。
自动模式
自动模式是默认的解析模式(也适用于目标合约中没有 “resolveMode” 方法的情况)。在自动模式下,如果 path 为空,则协议将使用空 calldata 调用目标合约。否则,EVM 消息的 calldata 将使用标准 Solidity 合约 ABI,其中
- method 是要调用的函数方法字符串
- argument_i 是该方法的第 i 个参数。如果指定了 type,该值将被转换为相应的类型。该协议目前支持 uint256、bytes32、address、bytes 和 string 等基本类型。如果未指定 type,则将按照以下顺序自动检测类型:
- type=”uint256”,如果 value 是数字;或者
- type=”bytes32”,如果 value 的格式为 0x+32-byte-data hex;或者
- type=”address”,如果 value 的格式为 0x+20-byte-data hex;或者
- type=”bytes”,如果 value 的格式为 0x 后跟除 20 或 32 之外的任意数量的字节;或者
- 否则 type=”address” 并将该参数解析为
[name "." [ subDomain0 "." ... ]] nsProviderSuffix
格式的域名。在这种情况下,参数的实际值将从 nsProviderSuffix 获得,例如 eth。如果不支持 nsProviderSuffix,将返回不支持的 NS 提供程序错误。
请注意,如果 method 不存在,即 path 为空或 “/”,则将使用空 calldata 调用该合约。
- query 中的 returns 属性指定了返回数据的格式。如果未指定,返回的消息数据将在 “(bytes32)” 中解析,并且 MIME 将根据最后一个参数的后缀设置。如果 returns 为 “()”,返回的数据将在 JSON 中以原始字节解析。否则,返回的消息将根据在 JSON 中指定的 returns 属性进行解析。如果存在多个 returns 属性,将应用最后一个 returns 属性的值。请注意,returnTypes 是 returns 的别名,但不建议使用,主要用于向后兼容。
示例
示例 1
web3://w3url.eth/
该协议将在 chainid 1(主网)中的 ENS 中查找 w3url.eth 的地址,然后协议将使用 “From” = “0x…” 和 “Calldata” = “0x2F” 调用该地址。
示例 2
web3://cyberbrokers-meta.eth/renderBroker/9999
该协议将在 chainid 1(主网)中的 ENS 中查找 cyberbrokers-meta.eth 的地址,然后使用 “To” = “0x…” 和 “Calldata” = “0x” + keccak("view(uint256)")[0:4] + abi.encode(uint256(9999))
调用该地址。
示例 3
web3://vitalikblog.eth:5/
该协议将在 chainid 5(Goerli)中的 ENS 中查找 vitalikblog.eth 的地址,然后使用 “From” = “0x…” 和 “Calldata” = “0x2F” 以及 chainid = 5 调用该地址。
示例 4
web3://0xe4ba0e245436b737468c206ab5c8f4950597ab7f:42170/
该协议将使用 “To” = “0x9e081Df45E0D167636DB9C61C7ce719A58d82E3b” 和 “Calldata” = “0x” 以及 chainid = 42170 (Arbitrum Nova) 调用该地址。
示例 5
web3://0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48/balanceOf/vitalik.eth?returns=(uint256)
该协议将在 chainid 1(主网)中的 ENS 中查找 vitalik.eth 的地址,然后使用 charles.eth 的地址调用合约的 “balanceOf(address)” 方法。返回的数据将被解析为 uint256,如 [ "10000000000000" ]
。
示例 6
web3://0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48/balanceOf/vitalik.eth?returns=()
该协议将在 chainid 1(主网)中的 ENS 中查找 vitalik.eth 的地址,然后调用该地址的 “balanceOf(address)” 方法。返回的数据将被解析为原始字节,如 ["0x000000000000000000000000000000000000000000000000000009184e72a000"]
。
理由
该提案的目的是为 Ethereum 添加一个去中心化的表示层。有了这一层,我们就能够在链上使用人类可读的 URL 渲染任何 Web 内容(包括 HTML/CSS/JPG/PNG/SVG 等),因此 EVM 可以用作去中心化的后端。该标准的设计基于以下原则:
-
人类可读。Web3 URL 应该像 Web2 URL (
http://
) 一样容易被人识别。因此,我们支持来自名称服务的名称来代替地址,以提高可读性。此外,我们使用人类可读的方法 + 参数,并将它们转换为 calldata,而不是使用十六进制的 calldata,以提高可读性。 -
与 HTTP-URL 标准最大程度地兼容。Web3 URL 应该与 HTTP-URL 标准(包括相对路径、查询、片段等)兼容,以便可以轻松地将对现有 HTTP-URL(例如,通过浏览器)的支持扩展到 Web3 URL,而只需进行最少的修改。这也意味着现有的 Web2 用户可以轻松迁移到 Web3,而只需掌握最少的本标准知识。
-
简单。我们没有在参数中提供显式类型,而是使用 “最大似然” 原则自动检测参数的类型,例如 address、bytes32 和 uint256。这可以大大缩短 URL 的长度,同时避免混淆。此外,如果需要,也支持显式类型以消除混淆。
-
灵活。合约能够覆盖编码规则,以便合约能够精细地控制理解用户想要定位的实际 Web 资源。
安全注意事项
未发现安全注意事项。
版权
通过 CC0 放弃版权和相关权利。
Citation
Please cite this document as:
Qi Zhou (@qizhou), Chao Pi (@pichaoqkc), Sam Wilson (@SamWilsn), "ERC-4804: Web3 URL 到 EVM 调用消息的转换," Ethereum Improvement Proposals, no. 4804, February 2022. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-4804.