跳到主要内容

签署数据

数据签名常用于登录验证、授权声明、订单确认和链下协议交互。UKey Wallet 会在用户确认后使用当前账户私钥生成签名,DApp 则负责展示清晰的签名目的并在服务端或合约端完成验签。

使用 UKey Wallet 发起签名

如果需要可运行参考实现,可参考 js-eth-personal-sign-examples

签名编码和验签工具可参考 eth-sig-util

签名方法选择

UKey Wallet 支持多种 Ethereum 签名方法。生产环境中应优先选择语义清晰、用户可理解且不容易被滥用的方法:

  • personal_sign
  • signTypedData(目前与 signTypedData_v1 相同)
  • signTypedData_v1
  • signTypedData_v3
  • signTypedData_v4

不同签名方法的安全属性不同,不能只看能否生成签名。

eth_sign 允许签署任意哈希,签名内容缺少明确上下文,存在被伪装成其他授权或交易的风险。因此不建议在生产环境使用。

如果旧系统确实依赖 eth_sign,请只在受控环境中使用,并在界面上明确说明签名风险。

personal_sign 会为消息添加 Ethereum 签名前缀,降低签名被解释成交易的风险。它适合登录、条款确认、一次性 nonce 挑战等场景。

如果签名需要被合约低成本验证,建议优先使用 EIP-712 结构化数据签名。

EIP-712 在演进过程中出现了多个版本,因此方法名中带版本号非常重要。为了兼容性,建议优先使用 eth_signTypedData_v4

Sign Typed Data v1

这是结构化签名的早期形式,缺少后续版本的一些安全和表达能力改进。除非需要兼容旧系统,否则不建议优先使用。

signTypedData 系列有几个主要的设计考虑:

  • 降低链上验签成本。
  • 让用户看到比原始哈希更可读的字段。
  • 通过 domain 和类型结构降低签名被挪用的风险。

如果只是新项目接入,请直接评估 v4。

Sign Typed Data v3

signTypedData_v3 是 EIP-712 的较成熟版本,适合需要结构化展示和链上验签的场景。

如果签名数据包含数组或更复杂的结构,请使用 v4。

合约端验签时,请确保 domain、type、message 的编码逻辑与前端完全一致。

Sign Typed Data v4

signTypedData_v4 是当前建议的 EIP-712 方法,支持数组并修复了结构体编码中的关键问题。

新项目如无特殊兼容需求,优先使用 eth_signTypedData_v4

Typed Data 消息入参

domain:用于限定签名有效范围,通常包含应用名、版本、链 ID 和验证合约等信息。它的作用包括:

  • 让签名只在指定应用、合约或网络中有效。
  • 降低不同 DApp 之间签名冲突或重放的风险。
  • 帮助用户识别当前签名属于哪个应用或合约。

chainId:用于绑定签名所属网络。

  • 如果签名包含正确的链 ID,测试网签名就不会被误用于主网。

name:主要用于用户识别签名来源。

  • 如果用户正在使用某个 DApp,但签名弹窗里出现另一个应用名,应当被视为风险信号。

verifyingContract:指定最终验证签名的合约地址,是防止同名应用混淆的重要字段。

  • 即使两个应用使用相同名称,合约地址也不同。
  • 如果没有合约,也可以根据协议设计使用其他能限定验证方的字段。

version:表示 domain 的版本,适合在协议升级时区分不同签名格式。

message:业务数据主体。字段由 DApp 自行定义,但应尽量保持用户可理解,避免只展示晦涩的编号或哈希。

下面是使用 UKey Wallet 签署 typed data 的参考。更多参考可见 这里

参考片段