EIP191、EIP712解析

由于EIP712是EIP191的一种,相当于EIP-712继承了EIP-191,所以就不过多解析EIP-191了。EIP-191简单来说EIP-191是为了定义智能合约中签名数据的格式。EIP191的数据格式为:0x19<1byteversion><versionspecific

由于EIP712是EIP191的一种,相当于EIP-712继承了EIP-191,所以就不过多解析EIP-191了。

EIP-191

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

EIP191的数据格式为:

0x19 &lt;1 byte version> &lt;version specific data> &lt;data to sign>.

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

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

version 0x00数据格式为:

0x19 &lt;0x00> &lt;intended validator address> &lt;data to sign>

version 0x45数据格式为:

0x19 &lt;0x45 (E)> &lt;thereum Signed Message:\n" + len(message)> &lt;data to sign>

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

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

  2. 是为了兼容交易。因为一开始并没有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中,把结构体名称,属性名称都编码进去了,因此钱包等第三方能够知道编码的结构体数据结构。

点赞 1
收藏 1
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
不可思议之人
不可思议之人
0x46b7...98ee
江湖只有他的大名,没有他的介绍。