Alert Source Discuss
Standards Track: ERC

ERC-681: 用于交易请求的 URL 格式

Authors Daniel A. Nagy (@nagydani)
Created 2017-08-01
Requires EIP-20, EIP-137

简单总结

一种表示各种交易的标准方式,特别是以太币和 ERC-20 代币的支付请求,以 URL 的形式。

摘要

嵌入在二维码、网页中的超链接、电子邮件或聊天消息中的 URL,为非常松散耦合的应用程序之间提供了强大的跨应用程序信号传递。用于支付请求的标准化 URL 格式允许立即调用用户首选的钱包应用程序(即使它是 webapp 或 swarm đapp),只需由(经过身份验证的)用户确认付款交易的正确参数。

动机

通过标准 URL 表示支付请求的便利性一直是比特币广泛采用的一个主要因素。 将类似的便捷机制引入以太坊将加快其作为终端用户支付平台的接受度。 尤其是在 broadcast Intents 中嵌入的 URL 是在 Android 操作系统上启动应用程序的首选方式,并且几乎适用于所有应用程序。 桌面 Web 浏览器有一种标准化的方式来定义具有特定协议规范的 URL 的协议处理程序。 其他桌面应用程序通常在遇到 URL 时启动 Web 浏览器。 因此,支付请求 URL 可以通过非常广泛且不断增长的渠道选择来传递。

本规范取代了已失效的 ERC-67,后者是一种以低级方式表示任意交易的 URL 格式。 此 ERC 专门关注支付请求的重要特殊情况,同时允许其他 ABI 指定的交易。

规范

语法

支付请求 URL 在其 schema (协议) 部分包含 “ethereum”,其构造方式如下:

request                 = schema_prefix target_address [ "@" chain_id ] [ "/" function_name ] [ "?" parameters ]
schema_prefix           = "ethereum" ":" [ "pay-" ]
target_address          = ethereum_address
chain_id                = 1*DIGIT
function_name           = STRING
ethereum_address        = ( "0x" 40*HEXDIG ) / ENS_NAME
parameters              = parameter *( "&" parameter )
parameter               = key "=" value
key                     = "value" / "gas" / "gasLimit" / "gasPrice" / TYPE
value                   = number / ethereum_address / STRING
number                  = [ "-" / "+" ] *DIGIT [ "." 1*DIGIT ] [ ( "e" / "E" ) [ 1*DIGIT ] ]

其中 TYPE 是一个标准的 ABI 类型名称,如 Ethereum Contract ABI specification 中所定义。 STRING 是一个 URL 编码的任意长度的 unicode 字符串,其中分隔符和百分号 (%) 必须使用前缀 % 进行十六进制编码。

请注意,number 可以用科学计数法表示,以 10 的幂为乘数。只允许整数,因此指数必须大于或等于小数点后的位数。

如果参数列表中的 keyvaluegasLimitgasPricegas,则 value 必须是 number。 否则,它必须对应于用作 keyTYPE 字符串。

有关 ENS_NAME 的语法,请参阅定义以太坊名称服务的 ERC-137

语义

target_address 是强制性的,表示原生代币支付的受益人(见下文)或要求用户与之交互的合约地址。

chain_id 是可选的,包含十进制链 ID,以便可以请求各种测试和专用网络上的交易。 如果不存在 chain_id,则客户端的当前网络设置仍然有效。

如果缺少 function_name,则 URL 请求以区块链的原生代币(在我们的例子中是以太币)支付。 数量在 value 参数中指定,以原子单位(即 wei)表示。 强烈建议使用科学计数法。 例如,请求将 2.014 ETH 发送到地址 0xfb6916095ca1df60bb79Ce92ce3ea74c37c5d359 如下所示: ethereum:0xfb6916095ca1df60bb79Ce92ce3ea74c37c5d359?value=2.014e18

请求以 ERC-20 代币支付涉及调用代币合约的 transfer 函数,该函数具有 addressuint256 类型的参数,分别包含受益人地址原子单位的数量。 例如, 请求将 Unicorn 发送到地址 0x8e23ee67d1332ad560396262c48ffbb01f93d052 如下所示: ethereum:0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7/transfer?address=0x8e23ee67d1332ad560396262c48ffbb01f93d052&uint256=1

如果使用 ENS 名称而不是十六进制地址,则解析由付款人决定,可以在收到 URL 和发送交易之间的任何时间进行。 十六进制地址始终优先于 ENS 名称,即,即使存在由 0x 后跟 40 个十六进制数字组成的匹配 ENS 名称,也绝不应解析它。 相反,应直接使用十六进制地址。

请注意,指示的金额只是一个建议(所有提供的参数也是如此),用户可以自由更改。 如果没有指示金额,则应提示用户输入要支付的金额。

同样,gasLimitgasPrice 是建议的用户可编辑的值,分别用于请求的交易的 gas 限制gas 价格。 可以将 gasLimit 缩写为 gas,两者被视为同义词。

理由

选择提出的格式是为了尽可能地类似于 bitcoin: URL,因为用户和应用程序程序员都已经熟悉该格式。 尤其是,这促使省略了以太坊生态系统中经常使用的单位。 指数有助于处理不同的数量级,以便金额值可以用其标称单位表示,就像 bitcoin: 的情况一样。 在以太币或 ERC-20 代币中表达货币价值时,强烈建议使用科学计数法。 为了更好的人类可读性,指数应该是标称单位的十进制值:以太币为 18,或 ERC-20 代币合约的 decimals() 返回的值。 如果实践中出现了需要它们的常用用例,则可以添加其他参数。

在指定为十六进制数的以太坊地址之前的 0x 前缀遵循已建立的实践,并且还明确区分了由 40 个字母数字字符组成的十六进制地址和 ENS 名称。

与此提案部分或完全不兼容的未来升级必须使用 pay- 以外的前缀,该前缀用破折号 (-) 字符与后面的任何内容分隔开。

向后兼容性

在仅指示以太币支付请求中的收款人地址的相当常见的情况下,此规范与已取代的 ERC-67 兼容。

安全考虑

由于可以使用此类 URL 中的参数启动不可逆的交易,因此这些 URL 的完整性和真实性非常重要。 尤其是,更改收款人地址或转移的金额可能是有利可图的攻击。 用户应仅使用从具有足够完整性保护的经过身份验证的来源收到的 URL。

为了防止使用 ENS 恶意重定向付款,对以太坊地址的十六进制解释必须优先于 ENS 查找。 如果 ENS 地址在视觉上与十六进制地址相似,或者甚至完全拒绝此类地址,则客户端软件可能会向用户发出警报,因为这可能是网络钓鱼攻击。

为了确保交易的金额与预期金额相同,传达给人类用户的金额应该易于通过检查来验证,包括数量级。 对于 ERC-20 代币支付,如果付款人客户端可以访问区块链或有关代币合约的某些其他可信信息来源,则该界面应以代币合约中指定的单位显示金额。 否则,应将其显示为 URL 中表示的形式,并可能提醒用户标称单位的不确定性。 为了方便人类检查金额,建议使用科学计数法,其指数对应于交易代币的标称单位(例如,以太币为 18)。

版权

Copyright and related rights waived via CC0.

Citation

Please cite this document as:

Daniel A. Nagy (@nagydani), "ERC-681: 用于交易请求的 URL 格式," Ethereum Improvement Proposals, no. 681, August 2017. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-681.