钱包签名信息显示标准化

该提案旨在标准化钱包(尤其是硬件钱包)显示的信息,通过正式定义 EIP-712 摘要、域名哈希、消息哈希以及新增的 Calldata 摘要,解决用户在签署复杂交易或大量数据时难以验证内容的问题,提高签名过程的透明度与安全性。

摘要

本 ERC 旨在实现以下两个目标:

  1. 设定钱包提供信息的标准

    • 对于 EIP-712 签名数据,钱包应始终提供显示 EIP-712 Digest(摘要)的选项。
    • 对于包含调用数据(calldata)的交易,钱包应始终提供显示 Calldata Digest 的选项。
  2. 定义 EIP-712 中的结果摘要

    • Domain Hash(域哈希):domainSeparator = hashStruct(eip712Domain)
    • Message Hash(消息哈希):hashStruct(message)
    • EIP-712 Digestencode(domainSeparator : 𝔹²⁵⁶, message : 𝕊) = "\x19\x01" ‖ domainSeparator ‖ hashStruct(message)

动机

在硬件设备上验证数据极具挑战性。近期发生的 Bybit(14 亿美元)、WazirX(2 亿美元)和 Radiant Capital(5000 万美元)黑客攻击事件表明,在设备上验证签名内容至关重要。由于网站可能被黑客攻击,我们不能信任网站发送给钱包的数据,必须完全依赖钱包来显示正确的信息。

对于 EIP-712 数据,如果设备显示整个结构体,用户要么依赖一台设备提取结构体并在另一台设备上验证,要么必须逐个字符肉眼比对。对于小型结构体这还可以接受,但对于大数据量,这项任务极其困难。

对于“普通”交易的 calldata,虽然可以对其进行解码以提高可读性,但开发者经常为了节省 Gas 而“打包”数据,导致其无法被正常解码。

此外,在签署智能合约钱包交易时,术语往往非常混乱。用户被要求签署 safeMessage,这与 EIP-712 计算出的结果不同。同时还有 SafeMessage hash,它既不同于 SafeMessage,也不同于 EIP-712 的摘要。如果 EIP-712 的计算结果有一个统一的名称,我们将更容易交流,避免像 Safe{Wallet} 中那样出现多个含义模糊的哈希术语。

不同术语示例:

  • Openzeppelin 隐式地称之为 “typed data hash”。
  • Safe{Wallet} 根据上下文称之为 safeTxHashSafeMessageHashsafeMessageMessage

规范

定义

EIP-712 Digest

EIP-712 标准中 encode(domainSeparator : 𝔹²⁵⁶, message : 𝕊) = "\x19\x01" ‖ domainSeparator ‖ hashStruct(message) 的计算结果,今后统称为 “EIP-712 digest”。

Domain Hash

EIP-712 将 domainSeparator 描述为 hashStruct(eip712Domain)。许多钱包和 UI 已开始将其称为 domain hash。本 ERC 旨在正式确立这一名称。

Message Hash

EIP-712 未对 hashStruct(message) 的计算结果定义正式名称。许多钱包和 UI 已将其称为 message hash。本 ERC 旨在正式确立这一名称。

Calldata Digest

这是一个针对交易中发送的 calldata 哈希的新术语,定义如下:

calldataDigest = keccak256(len(calldata) ‖ calldata)

Python 实现示例:

from eth_hash.auto import keccak
import binascii

def compute_calldata_digest(calldata):
    if isinstance(calldata, str) and calldata.startswith("0x"):
        calldata = binascii.unhexlify(calldata[2:])
    length = len(calldata)
    length_bytes = length.to_bytes(32, byteorder="big")
    combined = length_bytes + calldata
    return "0x" + keccak(combined).hex()

原理

假设我想执行以下操作:

  1. 使用 approve 函数授权 ERC20 代币存入 Aave。
  2. 使用 supply 函数将代币存入 Aave。
  3. 使用 Safe{Wallet} 智能合约钱包进行批量交易。

在签署 EIP-712 类型数据时,Metamask 等软件钱包的界面如下:

data 部分填充了与批量交易相关的 calldata。在电脑上,复制并验证这些数据并不难。但让我们看看不同硬件钱包上的显示情况:

Gridplus(有 3 页类似数据):

Trezor(有 8 页类似数据):

Ledger(由于页数过多,Ledger 会直接停止显示):

目前用户只能:

  1. 肉眼检查 EIP-712 结构体和 calldata。
  2. 使用另一台设备从硬件钱包中提取数据。

肉眼检查极易出错,哪怕漏掉一位数字也可能导致灾难。而强制钱包连接外部源进行验证也不是理想方案。

改进方案:EIP-712 签名

对于 EIP-712 数据,我们可以在底部显示摘要(Ledger 目前已显示 Message Hash 和 Domain Hash,它们可以组合成 EIP-712 摘要)。

用户可以自行计算 EIP-712 哈希,并与钱包上显示的摘要进行对比。

改进方案:交易(Transactions)

对于普通交易,我们建议将 calldata digest 放置在钱包界面的底部。

改进方案:智能合约钱包

Safe{Wallet} 等智能合约钱包可以使用一致的术语。用 EIP-712 digest 代替 safeTxHash;用 SafeMessageEIP-712 digest 代替容易混淆的 SafeMessageSafeMessage Hash

示例工作流

  1. 用户发起交易或 EIP-712 签名。
  2. 用户可以选择:
    • 浏览整个结构体/calldata 以确保正确。
    • 使用 safe-hashsafeutils 等工具计算 calldata digesteip-712 digest,并与钱包上的摘要对比。
    • 使用配合硬件钱包的软件钱包来查看生成的摘要。
  3. 用户确认签名内容无误。

向后兼容性

本 ERC 不会对以太坊核心产生任何影响。它仅是增量改进,不会影响向后兼容性。

安全考量

黑客可能会尝试针对大型 calldata 或 EIP-712 结构体“碰撞”出一个匹配用户预期摘要的恶意数据。目前我们认为这在计算上是不可行的。

我们在 calldata 摘要中特意未包含 chainIddeadline,因为我们认为用户应该能够在不同链或时间对相同的 calldata 使用相同的摘要。

如果用户依赖软件钱包(如 Metamask、Rabby)来显示这些新摘要,安全性压力将转移到软件钱包上。用户不再信任网站,而是信任其软件钱包或摘要计算工具。

致谢

Argent 团队过去曾做过类似尝试:将新账户地址哈希并转换为表情符号(emoji)显示给用户。这样非技术用户可以通过比对表情符号来确认地址是否正确。

进一步考量

1. 使用表情符号摘要(Emoji Digests)

可以考虑显示表情符号而不是十六进制数据。对于不熟悉十六进制的用户,“鸭子、旗帜、树、青蛙”比一长串字符更容易记忆和比对。

2. 添加新的 EIP-191 类型

为了进一步节省 Gas,可以将 EIP-712 摘要和 calldata 摘要转变为新的 EIP-191 类型。这样开发者可以让用户签署 calldata,而无需在链上或交易中存储完整的 calldata。

3. 结合 AI 进行 Calldata 解码

利用 AI 模型解码 calldata 并用自然语言解释交易是一个有趣的方向。虽然目前存在隐私和准确性风险,但已有类似 Pranesh 的 MCP 示例 等初步尝试。

版权

通过 CC0 放弃版权及相关权利。

  • 原文链接: ethereum-magicians.org/t...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
以太坊中文
以太坊中文
以太坊中文, 用中文传播以太坊的最新进展