permit permit2 EIP712 都是什么,和 离线签名有关系吗

EIP-712 被提出的原因

EIP-712 是以太坊一种结构化签名的方式。用户用私钥对一个未经过“结构化”的消息进行签名,是一串十六进制字节码,这种消息很难让签名人看懂,体验不好,而且会被一些作恶的应用或网站利用(例如让用户签一个操作把 token 授权给某个地址,然后资产就被盗取,而用户难以在签名时意识到)。例如下面这种签名,只能看懂地址和转账信息,但是 Message 中的字节码无法被人类读懂。

eth_signData

EIP-712 就是解决这种看不懂的情况,同时也提升用户体验,把消息结构化出来,告诉签名人要签的消息有哪些内容。

EIP-712 快速上手

EIP-712 结构化签名包含 3 个部分:

  • EIP712Domain:保证离线签名只有在指定链的通过指定的合约(指定版本)才能被正确地通过验证。

  • name:签名域的用户可读名称,即 DApp 或 Protocol 的名称。

  • version:签名域的当前主要版本。不同版本的签名不兼容,这个一般取值为 1
  • chainId:链 ID,用于验签时检查是否在签名者许可的那条区块链网络。
  • verifyingContract:验证签名的合约地址(例如,用户通过离线签名允许某合约使用自己 100 个 A token,验证签名的合约就是 A token 合约。

举例如下:

javascript const domain = { name: "Garen Test Safe Token", version: "1", chainId: "80001", // e.g. Polygon Mumbai Testnet verifyingContract: "0x94B1424C3435757E611F27543eedB37bcD3BDEb4", };

  • types:待被签名的数据的类型。根据业务逻辑的需要决定签署哪些字段或变量。如下的代码中,指定了签名中包含的 5 个数据,并分别指定数据类型。其中:

  • nonce 是防止重用签名的一个自增数,通过链上读取合约内的这个值(不需要发交易,静态调用即可),每当签名被验证通过(被使用掉了),这个值就会自增,以此达到防止一个离线签名被多次使用的问题,一般来说,这个字段是大多数离线签名所需的。

  • deadline 表示签名的有效期。

JavaScript const types = { Permit: [ { name: "owner", type: "address" }, { name: "spender", type: "address" }, { name: "value", type: "uint256" }, { name: "nonce", type: "uint256" }, { name: "deadline", type: "uint256" } ], };

  • message:待被签名的数据的值。应与 types 中指定的变量或字段一一对应,分别指定它们的值。

JavaScript const message = { owner: owner, spender: spender, value: value, nonce: nonce, deadline: deadline, };

通过 Ethers.js 库可将这 3 个部分组装并通过浏览器中注入的钱包对象来让用户签名。用户即可在前端页面中看到例如如下面的签名界面:

eth_signTypedData

使用 EIP-712 进行离线签名的示例代码

对于某个实现了 ERC2612(或 ERC20Permit,即合约中包含了验签方法)的 token,用户采用离线签名对某个地址进行授权一定的额度 Value,允许其作为 Spender 使用此用户的 token 。

点击访问前端代码,关键点解释如下:

// 379 行:获取浏览器注入的钱包对象 `provider`
const provider = new ethers.BrowserProvider(window.ethereum)

// 380 行:从钱包对象 `provider` 获取 `signer`(这是一个包含私钥的对象,用于发起交易或者签名)
const signer = await provider.getSigner()

// 426 行:通过 `signer` 对信息(domain、types 和 message)进行签名
const signedMessage = await signer.signTypedData(domain, types, message);

// 428 行:使用签名信息生成 3 个参数 v, r, s(ESDCA 生成),用于后续的链上验签。
const signatureResult = ethers.Signature.from(signedMessage);
console.log("v: ", signatureResult.v);
console.log("r: ", signatureResult.r);
console.log("s: ", signatureResult.s);

应用案例

全部回复(1)
seek CTO

牛逼,直接回答了

点赞
回复
我来回答
热门问答
memo 是什么,在中心化钱包开发中有什么作用,请举例说明那些链带有 Memo, Memo 另一个名字是什么
BIP-32、BIP-39、BIP-44 和 BIP-86 是比特币改进提案中的一部分,分别解决了什么问题?
permit permit2 EIP712 都是什么,和 离线签名有关系吗
发生硬分叉时,做为钱包的开发,您应当怎么去处理这种状况, 以 ETHPOW 和 ETH2.0 分叉这个过程
为什么 schnorr 比特币手续费可以降低
有用过 rosetta api, 请简单描述起作用,并举几个钱包常用的接口说明
Solana 和 Tezos 质押流程描述
MPC GG20 算法 Keygen 和 Sign 分别需要经过多少轮共识
Cosmos 新版本和老版本签名异同点
关于Ton链的wallet-sdk生成地址的问题
两种执行publicKey 的结果不一致
HD 钱包助记词生成的流程
solana 交易签名有有效期说法吗?若有情描述什么场景的签名会出现这种状况,怎么去解决?
TON 支持合约吗?若支持,请说出其合约开发语言
.描述一下交易钱包的充值和提现流程
谁能总结一下 KDA 的特性
简要说明 EOS 账户的激活过程,EOS 同源的有哪些链
ETH2.0 的 epoch, slot 和 block 简述
助记词的验证过程
Cosmos 钱包资金精度,Cosmos 签名结构中的 account_number 和 seqence 怎么获取
去中心化和中心化钱包开发中的异同点有哪些?
Cosmos 共识算法是什么
LSD 产品的质押流程(以 lido 为例说明)
简单描述以太坊交易类型,并说明这个交易类型的作用
cosmos-sdk 的应用场景
描述一些 UTXO 和账户模型的区别
ERC721 和 ERC1155 区别与联系
关于solana的质押,是不是任意两个account之间就可以进行质押
相比较之下 EDDSA 性能,安全性都会高一些,为什么比特币以太坊用了 ECDSA,没有用 EDDSA
比特币的地址有哪些格式,请说明
为什么比特币早期时候不直接用 schnorr 签名算法
解释一下什么是 EVM 同源链,举例说明一下
SOL生成地址调用derivePath比ETH生成地址调用derivePath少一层
生成助记词,128位生成6个助记词,而不是12个
简述 Cosmos 的 Interchain Security 和 IBC Protocol
Ton钱包
我通过钱包的创建出来的solana私钥长度为86位,但是通过keyPair.generate生成的secretKey为128位
kda跨链转账问题
对于没有ts库的链,怎么方便调研
kda测试用例问题
ton钱包地址格式
Sui发送交易RPC接口问题
kadena钱包地址对不上
对solana交易进行签名的时候,是不是只需要签交易发起账户就可以了
Keypair.fromSecretKey 的时候,这个skipValidation是否可以去掉
我的phantom钱包的solana秘钥86位,但是keyPair.generate().secretKey得到的秘钥128位
compile.sh 这个脚本触发是写在哪的?
opio.WithInterruptBlocker(context.Background()) 这段代码的核心作用是啥,能否去掉
针对./rpc-service rpc 这个名利,有没有那种可以debug模式执行的方式
使用go grpc调用node.js 的离线签名应该怎么搞
我看了针对Http接口设置了超时机制,对应的grpc服务是否也需要设置超时,重试相关的机制呢
我们如果自己定义的这个grpc服务,我们的服务注册和服务发现会怎么弄。
下面两个方法使用指针作为方法接收方会不会好一点
我看到httpUtil里面的的Close,Closed,Stop,Shutdown相关的四个方法,有点看不明白
链适配器工厂映射这个map没有看太明白
关于手续费问题
交易所钱包,我们会对链上的本币进行归集,但是类似于ERC20,ERC721这些代币需要归集吗
如果一条公链发生硬分叉之后,交易所一般需要做哪些动作