EIP191、EIP712解析

EIP-191


简单来说EIP-191是为了定义智能合约中签名数据的格式

EIP191的数据格式为:

0x19 <1 byte version> <version specific data> <data to sign>.

这其中的<1 byte version>用来确定EIP191的版本。

目前一共有三个版本号:0x00,0x01,0x45。其中0x01即为EIP712。

version 0x00数据格式为:

0x19 <0x00> <intended validator address> <data to sign>

version 0x45数据格式为:

0x19 <0x45 (E)> <thereum Signed Message:n" + len(message)> <data to sign>

之所以使用0x19作为前缀:

  1. 是为了和RLP编码区分。

  1. 是为了兼容交易。因为一开始并没有EIP191格式,人们常用的是最初由Geth实现的 personal_sign方案,数据格式为:

"x19Ethereum Signed Message:n" + length(message) + message

而人们往往会对message做哈希运算,因此更常见的格式为:

"x19Ethereum Signed Message:n32" + Keccak256(message)

为了兼容这类交易,就以0x19为前缀,再把第一个字母“E”作为版本号。

EIP712


EIP712是EIP191的改良版,用于改良EIP191中存在的问题。

EIP191有几个问题:

  1. 没有明确防止重访攻击的规定。

  2. 没有编码规范,造成一些外部组件,比如钱包,无法解析编码,导致用户无法了解签名内容。

EIP712就是为了解决以上两个问题:

  1. 通过DOMAIN_SEPARATOR设定,防止重放攻击。

  2. 规范对结构体编码的方式,使签名内容可视化,高签名时的安全性。

  • 防止重放攻击


EIP-712结构如下:

encode(domainSeparator,message)=x19x01/domainSeparator/hashStruct(message)

其中的x19x01与hashStruct(message)就不解释了,我们主要看domainSeparator字段,这才是防止重入的关键。

domainSeparator字段结构如下:

domainSeparator = keccak256(typeHash / encodeData(S))

typeHash为一个结构体的编码再进行keccak256,结构体如下:

struct EIP712Domain{    string name,     string version,     uint256 chainId,     address verifyingContract,     bytes32 salt }

encodeData是上述结构体中的参数的编码。

需要注意的是,结构体中的字段可以省略,但不可以颠倒顺序。

  • 签名内容可视化


EIP712通过规范对结构体编码的方式来使签名内容可视化。其主要体现在hashStruct(message)字段中。

hashStruct(message)字段结构如下:

hashStruct(message) = keccak256(typeHash / encodeData(S))

与domainSeparator字段类似,因此就不再赘述了。

可以看到messageHash中,把结构体名称,属性名称都编码进去了,因此钱包等第三方能够知道编码的结构体数据结构。


作者:于文杰

编辑:舒婷



原文始发于微信公众号(ChainSecLabs):EIP191、EIP712解析

版权声明:admin 发表于 2024年5月7日 下午1:20。
转载请注明:EIP191、EIP712解析 | CTF导航

相关文章