文章目录
- 前言
- 一、Permit介绍
- 什么是Permit模式
- Permit解决了什么问题
- 实现的原理
- 传统授权模式
- 二、Permit2介绍
- 什么是Permit2
- Permit2授权模式
- Permit2可能存在的风险
- 三、Permit和Permit2对比
- 总结
前言
随着区块链技术的不断发展,智能合约在去中心化应用(DApps)中的应用变得越来越广泛。然而,传统的授权模式存在一些安全性和用户体验上的问题。为了解决这些问题,提出了基于ERC-2612的Permit模式,并进一步推出了Permit2协议。本篇文章将详细介绍Permit和Permit2两种授权模式,分析它们各自的实现原理和优缺点
一、Permit介绍
什么是Permit模式.
permit
是基于 ERC-2612 提案的一种授权机制,通过使用签名消息进行验证,通过链下授权就可以操作token.
Permit解决了什么问题
- 用户不需要额外提交一个链上的approve()交互。
- 由于省掉了一笔链上操作所以可以通常可以选择一个更合理的授权额度,而不是无限大,更重要的是在签名授权消息时可以设置一个到期时间。
虽然 EIP-2612 使Token授权更加安全,但在 EIP-2612 之前推出的Token并不支持签名授权功能,而且并非所有较新的Token都采用该功能。因此该协议很难大范围的使用。 (这解决了典型 ERC20 授权方法的两个问题)
实现的原理
- Alice签署一个链外的 "permit(签名授权)" 信息,表示她希望授予一个合约一个(EIP-2612)Token的使用权。
- Alice提交签署的消息,作为她与所述合约交互的一部分。
- 合约调用Token上的 "permit()" 方法,它会使用签名授权信息和签名,同时授予合约一个授权。
- 合约现在有了授权,所以它可以在Token上调用transferFrom(),转账由 Alice 持有的Token。
由于Permit (EIP-2612) 需要把相关方法写入ERC20Token合约内,所以已经部署的ERC20合约无法进行支持。
EIP-2612 标准代码:
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) public virtual {
if (block.timestamp > deadline) {
revert ERC2612ExpiredSignature(deadline);
}
bytes32 structHash = keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));
bytes32 hash = _hashTypedDataV4(structHash);
address signer = ECDSA.recover(hash, v, r, s);
if (signer != owner) {
revert ERC2612InvalidSigner(signer, owner);
}
_approve(owner, spender, value);
}
这段代码的关键点包括:
- 使用
block.timestamp
来检查签名是否过期。 - 使用 EIP-712 标准编码创建一个结构哈希,以确保签名的唯一性和正确性。
- 使用 ECDSA 来验证签名的合法性,确保签名者是代币所有者。
- 最后,执行实际的代币授权操作,允许 spender 在代币所有者的名义下转移指定数量的代币
传统授权模式
1.Alice调用ERC20上的approve()来授予合约的支配限额。
2.Alice在合约上调用一个交互函数,该函数又在ERC20 Token合约上调用transferFrom(),移动她的Token。
显然,这个模型是可行的(它是普遍存在的),并且最终可以非常灵活,因为协议通常会不间断地长期访问用户的Token。
授权合约默认获取最大数量支配Token的权限,并且没有时间的限制,不同的DApp首次执行都需要授权一次,具有很大风险。
它面临着两个现实问题:
- 糟糕的用户体验:用户必须授权他们打算使用的每个Token上的每个新协议,而这几乎总是一个单独的事务(例如在uniswap中执行了某个Token授权,但是如果使用 transit 依然需要重新进行approve)。
- 糟糕的安全性:合约通常都会要求无限的授权额度,并且每使用一个swap或者其他合约都用都需要执行一次approve。这意味着,如果该协议被利用,每个用户授权该协议消费的Token都有可能把用户的授权Token全部转移。(例如我们经常会遇到的Token使用授权,例如操作DeFi需要授权,进行兑换需要授权,不同的DApp首次使用都需要授权)
因此最后如果使用Permit方式就能彻底解决此问题.
二、Permit2介绍
什么是Permit2
Permit2是Uniswap 发布新的Token授权标准 ,它是permit的升级版,解决传统 permit
存在的一些限制,并引入更多功能和灵活性.
Permit2 协议让其他应用可以从整合这些合约中大大受益。Uniswap 本身致力于建设公共基础设施,因此设计了这些合约,提供整个开发者生态系统使用,包括广泛的文档、SDK
EIP-2612升级版
Permit2 授权模式
Permit2 结合了这两种模式,将 EIP-2612 的用户体验和安全优势扩展到也涵盖了普通的 ERC20 Token。
- 用户签署一个链下permit2 消息,该消息表明协议合约被允许代表她转账代Token
- 在协议合约上调用一个交互函数,将签署的 permit2 消息作为参数传入.
- 通过验证授权之后,会在permit2的函数里面操作permitTransferFrom, 或者transferFrom 再调用token contract的转账.(正常的permit函数通过验证之后,直接操作token contract,而permit2会包装了一层业务.)
将授权给与Permit2后,使用了Permit2协议的DApp 只需要进行一次712的本地签名就可以,不需要额外的链上approve,降低了Gas费用,增加了易用性和安全性。授权具有时限性,例如授权一个月,那么一个月时间过期后下次使用同样只需要一次712签名即可。
协议不会直接调用 ERC20 Token上的transferFrom()来执行转账,而是调用规范的 Permit2 合约上的permitTransferFrom()。Permit2 位于协议和 ERC20 Token之间,跟踪和验证 permit2 消息,然后最终使用其授权直接在 ERC20 上执行transferFrom()调用。这种间接性使得 Permit2 可以将类似于 EIP-2612 的好处扩展到每一个现有的 ERC20 Token上。
Permit2 协议具有的优点
- 统一的Token管理。
- 可控制的授权时间。
- 不用每次都多发一笔交互来进行授权。
Permit2 协议可能存在的风险
- 号称解决了 infinity approval 的问题,但实际只是把授权对象从需要交互的 DApp 转变成了 Permit2 合约,集中管理授权对 Permit2 合约的安全性有着更高的要求。
- 虽然说Token授权有过期时间,但是这个时间依旧可以无限大,还是需要各个Dapp合理的设置过期时间。
- 由于调用 permit 函数的过程可以不发送交互而是只提供签名给第三方代发,如果是做钓鱼的话可以做得更加隐蔽,用户检查签名消息的成本提升,某些第三方钱包可能不会对签名信息进行解码展示,导致用户被攻击的风险更高。
三、Permit和permit2对比
特点 / 改进点 | permit | permit2 |
---|---|---|
适用范围 | 主要用于 ERC-20 代币 | 不限于 ERC-20,可以扩展到其他类型的合约 |
功能 | 简化 gas 费用,省略授权步骤 | 支持更复杂的授权机制,不限于代币转移 |
安全性 | 基本的签名验证机制 | 引入更多参数和检查,提高安全性和灵活性 |
管理 | 单一授权管理 | 允许在一个合约中管理多个授权 |
操作类型 | 仅限于 approve 和 transfer | 支持多种操作类型,如 permit2,execute 等 |
集成性 | 可能需要对每个代币合约进行修改 | 更易集成到现有智能合约中,无需修改每个代币合约 |
扩展性 | 有限 | 更灵活和通用,支持更多的智能合约和应用场景 |
总结:
优点和风险同时存在,这就需要我们具有一定的辨别能力,具体到钱包方也需要对后续可能大范围支持Permit2 有一个提前的防范,(现在TokenPocket 还没支持 Permit2 的解析,后面很快会支持。)例如TokenPocket 现在的授权风险提示等弹窗,就可以很好的把风险内容进行展示,从而避免因为钓鱼或第三方恶意授权等风险。
不要随意打开不明来历的网站并执行,一定要使用正规的DApp并尽可能的控制好授权给合约的Token数量,时常用授权检测工具进行检查。
此方案提高了体验度,但是牺牲了一定程度的安全性,使用时希望谨慎考虑安全方面.
资料