首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Uniswap Permit2 - 高效、一致和安全的授权

Uniswap Permit2 - 高效、一致和安全的授权

作者头像
Tiny熊
发布于 2023-01-09 09:46:58
发布于 2023-01-09 09:46:58
1.9K00
代码可运行
举报
运行总次数:0
代码可运行

本文作者:翻译小组[1]

前几天,Uniswap Labs 发布了两个新的智能合约 Permit2 和 Universal Router :

  1. Permit2 [2] 允许代币授权在不同的应用程序中共享和管理,创造一个更统一、更具成本效益、更安全的用户体验。
  2. Universal Router[3] 将 ERC20 和 NFT 兑换统一到一个单一的兑换路由器。与 Permit2 整合后,用户可以在一次兑换交易中兑换多个代币和 NFT,同时节省 Gas 费。

Uniswap 最初构思 Permit2 和 Universal Router 是为了改进 Uniswap 自己的产品,优化 Gas 成本,简化用户交易流程,并加强安全性。在构思的过程中,Unswap 觉得其他应用可以从整合这些合约中大大受益。Uniswap 本身致力于建设公共基础设施,因此设计了这些合约,提供整个开发者生态系统使用,包括广泛的文档、SDK

Permit2[4]是一个代币授权合约,可以在不同的智能合约中安全地共享和管理代币授权。随着越来越多的项目与 Permit2 集成,可以在所有应用程序中对代币授权进行标准化。反过来,Permit2 将通过降低交易成本来改善用户体验,同时提高智能合约的安全性。

典型授权模式

以下是EIP-20[5]中定义的典型代币授权(Approve)方法图示:

  1. Alice 在一个 ERC20 上调用approve(),向一个合约授予支出授权。
  2. Alice 在合约上调用一个交互函数,该函数又在 ERC20 代币合约上调用transferFrom(),转账她的代币。

显然,这种模式是可行的(它无处不在),并且最终可以相当灵活,因为协议通常会最终不间断地长期访问用户的代币。但它有两个众所周知的现实世界的问题。

  • 糟糕的用户体验, 用户必须对他们打算使用的每个代币授权给每个新的协议,这导致了混乱的用户体验,同时这几乎总是一个单独的交易,浪费了 Gas 和时间。
  • 糟糕的安全性,应用程序通常要求用户授权最大限额,以避免重复上述用户体验问题。这意味着,如果协议被利用,每个用户授权协议使用的代币都有可能被直接从他们的钱包里拿走(因为应用程序可以无限期地访问钱包的整个代币余额)。

授权签名(EIP-2612)模型

EIP-2612[6] 对代币的授权进行了迭代。用户可以通过在他们的交易中附加一个授权签名(Permit)信息来与应用合约交互,而不需要事先授权。

让我们看看 ERC20 的 EIP-2612 扩展所启用的方法,它通常是这样的:

  1. Alice 签署一个链外的 "permit(签名授权)" 信息,表示她希望授予一个合约一个(EIP-2612)代币的使用权。
  2. Alice 提交签署的消息,作为她与所述合约交互的一部分。
  3. 合约调用代币上的 "permit()" 方法,它会使用签名授权信息和签名,同时授予合约一个授权。
  4. 合约现在有了授权,所以它可以在代币上调用transferFrom(),转账由 Alice 持有的代币。

这解决了典型 ERC20 授权方法的两个问题:

  • 用户永远不需要提交一个单独的approve()交易。
  • 不再有悬空授权的必要之恶,因为许可消息授予的是即时授权,通常会立即花费。因此也可以选择一个更合理的授权额度,更重要的是,在签名授权消息可以被使用代币的时间上有一个到期时间。

虽然 EIP-2612 使代币授权更加安全,但在 EIP-2612 之前推出的代币并不支持签名授权功能,而且并非所有较新的代币都采用该功能,这就是悲催的现实。因此大多数时候,这种方法不可行。

关于 EIP-2612, 我那个登链社区上还有一些文章探讨,可参考这里[7]

Permit2 模式

最后,让我们深入探讨 Permit2 的方法,Permit2[8] 结合了这两种模式,将 EIP-2612 的用户体验和安全优势扩展到也涵盖了普通的 ERC20 代币!

为了说明 Permit2 的革命性,在一个常见的场景中,协议需要转账 Alice 持有的代币。

  1. Alice 在一个 ERC20 上调用approve(),典型的方式为的 Permit2 合约授予一个无限的授权。
  2. Alice 签署一个链下 permit2 消息,该消息表明协议合约被允许代表她转账代币。
  3. Alice 在协议合约上调用一个交互函数,将签署的 permit2 消息作为参数传入。
  4. 协议合约在 Permit2 合约上调用 permitTransferFrom(),而 Permit2 合约又使用其授权(在 1 中授予)在 ERC20 合约上调用 "transferFrom()",转账 Alice 持有的代币。

要求用户首先授予一个明确的授权交易,这似乎是一种倒退。但是,用户不是直接授予协议,而是将其授予规范的 Permit2 合约。这意味着,如果用户之前已经这样做了,比如说与另一个集成了 Permit2 的协议进行交互,那么其他每一个协议都可以跳过这个步骤。

这太棒了。

协议不会直接调用 ERC20 代币上的transferFrom()来执行转账,而是调用规范的 Permit2 合约上的permitTransferFrom()。Permit2 位于协议和 ERC20 代币之间,跟踪和验证 permit2 消息,然后最终使用其授权直接在 ERC20 上执行transferFrom()调用。这种间接性使得 Permit2 可以将类似于 EIP-2612 的好处扩展到每一个现有的 ERC20 代币上。🎉

同时,像 EIP-2612 签名授权信息一样,Permit2 信息也会过期,以限制漏洞的攻击窗口。

集成 Permit2

对于集成 Permit2 的前端来说,它需要获取一个用户签名,并将其传递到交易中。这些签名签署的 Permit2 消息结构(PermitTransferFrom)必须符合EIP-712[9]标准(社区有一些相关文章[10]),使用这里[11]和这里[12]定义的 Permit2 域和类型散列。请注意,EIP-712 Permit2 对象的 spender字段需要被设置为将要消费它的合约地址。

智能合约的整合实际上是相当容易的! 任何需要转账用户持有的代币的函数只需要接受任何的许可信息细节和相应的 EIP-712 用户签名。为了实际转账代币,我们将在规范的 Permit2 合约上调用permitTransferFrom()。该函数的声明为:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    function permitTransferFrom(
        PermitTransferFrom calldata permit,
        SignatureTransferDetails calldata transferDetails,
        address owner,
        bytes calldata signature
    ) external;

这个函数的参数是:

  • permit - permit2 消息的详情, 有下面的信息。
    • token - 要转账的代币的地址。
    • amount - 此签名信息可转移的最大金额。
    • permitted 一个TokenPermissions结构,有以下字段:
    • nonce - 一个独特的数字,用来防止重用签名许可。一旦签名许可被使用,任何使用该 nonce 的其他签名许可将无效。
    • deadline - 该签名许可有效的截止时间。
  • transferDetails - 一个包含转账接收人和转账金额的结构,可以小于用户签名的金额。
  • owner - 签署许可的人,也是持有代币。通常,在简单的使用场景中,调用者和用户是同一个人,这应该被设置为调用者(msg.sender)。但在更奇特的集成中,你可能需要更复杂的检查[13]
  • signature - permit2 信息对应的 EIP-712 签名,由owner签名。如果从签名验证中还原的地址与 owner不一致,调用将失败。

注意,PermitTransferFrom结构不包括签名信息 EIP-712 typehash 定义[14]中的spender字段。在处理过程中,它将被填入我们的合约地址(permitTransferFrom()的直接调用者)。这就是为什么用户签署的 EIP-712 对象的spender字段必须是这个合约的地址。

高级集成

前面涵盖了 Permit2 提供的基本功能,但你还可以用它做更多的事情!

  • 自定义见证数据[15] - 你可以将自定义数据附加到 permit2 的信息中,这意味着 Permit2 的签名验证也将扩展到验证这些数据。
  • 批量转账[16] - 一个用于执行多个转账的批量 permit2 消息,由一个签名来保证。
  • Smart Nonces[17] - 在底层,nonces 实际上被写成存储槽中的位字段,并以上面的 248 位为索引。你可以通过仔细选择重用存储槽的 nonce 值来节省大量的 Gas。
  • 回调签名[18] - Permit2 支持EIP-1271[19]回调签名,它允许智能合约也签署 permit2 消息。
  • Permit2 Allowances[20] - 对于需要更多灵活性的协议,Permit2 支持一个更传统的授权模型,得到了过期时间的额外好处。

The Demo

这里提供的示例代码[21]是一个简单的金库,用户可以使用 Permit2 将 ERC20 代币存入其中,随后可以提取。因为它是多用户的,它需要启动转账,以便可靠地记入哪个账户拥有哪个余额。通常情况下,这需要给金库合约授予授权,然后让金库对代币本身执行transferFrom(),但 Permit2 让我们跳过了这个麻烦!

Test 用例[22]部署了一个本地的、字节码的主网 Permit2 合约的分叉,以测试金库的一个实例。EIP-712 Hash 和签名生成也是用 solidity/foundry 编写的,但通常应该在链外用你选择的语言在前端或后端执行。

参考资源

  • Permit2 公告[23] - Permit2 的地址也可以在这里找到
  • Permit2 Repo[24] - Permit2 智能合约代码
  • Permit2 `SignatureTransfer` 文档[25] - 由 Uniswap 提供的 Permit2 官方文档
  • Permit2 解释[26]

参考资料

[1]

翻译小组: https://learnblockchain.cn/people/412

[2]

Permit2 : https://github.com/Uniswap/permit2

[3]

Universal Router: https://github.com/Uniswap/universal-router

[4]

Permit2: https://github.com/Uniswap/permit2

[5]

EIP-20: https://eips.ethereum.org/EIPS/eip-20

[6]

EIP-2612: https://eips.ethereum.org/EIPS/eip-2612

[7]

参考这里: https://learnblockchain.cn/tags/EIP2612

[8]

Permit2: https://github.com/Uniswap/permit2

[9]

EIP-712: https://eips.ethereum.org/EIPS/eip-712

[10]

相关文章: https://learnblockchain.cn/tags/EIP712

[11]

这里: https://github.com/Uniswap/permit2/blob/main/src/EIP712.sol

[12]

这里: https://github.com/Uniswap/permit2/blob/main/src/libraries/PermitHash.sol

[13]

你可能需要更复杂的检查: https://docs.uniswap.org/contracts/permit2/reference/signature-transfer#security-considerations

[14]

签名信息 EIP-712 typehash 定义: https://github.com/Uniswap/permit2/blob/main/src/libraries/PermitHash.sol#L21

[15]

自定义见证数据: https://docs.uniswap.org/contracts/permit2/reference/signature-transfer#single-permitwitnesstransferfrom

[16]

批量转账: https://docs.uniswap.org/contracts/permit2/reference/signature-transfer#batched-permittransferfrom

[17]

Smart Nonces: https://docs.uniswap.org/contracts/permit2/reference/signature-transfer#nonce-schema

[18]

回调签名: https://github.com/Uniswap/permit2/blob/main/src/libraries/SignatureVerification.sol#L43

[19]

EIP-1271: https://eips.ethereum.org/EIPS/eip-1271

[20]

Permit2 Allowances: https://docs.uniswap.org/contracts/permit2/reference/allowance-transfer

[21]

示例代码: https://github.com/dragonfly-xyz/useful-solidity-patterns/blob/main/patterns/permit2/Permit2Vault.sol

[22]

Test用例: https://github.com/dragonfly-xyz/useful-solidity-patterns/blob/main/test/Permit2Vault.t.sol

[23]

Permit2公告: https://uniswap.org/blog/permit2-and-universal-router

[24]

Permit2 Repo: https://github.com/Uniswap/permit2

[25]

Permit2 SignatureTransfer 文档: https://docs.uniswap.org/contracts/permit2/reference/signature-transfer

[26]

Permit2 解释: https://github.com/dragonfly-xyz/useful-solidity-patterns/tree/main/patterns/permit2

Twitter : https://twitter.com/NUpchain Discord : https://discord.gg/pZxy3CU8mh

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-12-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 深入浅出区块链技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Uniswap V2 源码学习 (四). 签名和路由
上次我们在研究 router 合约的时候, 有一个 removeLiquidityWithPermit 函数[2], 今天讲讲它和 Pair 的 permit 方法
Tiny熊
2022/05/25
1.4K0
通过链下签名授权实现更少 Gas 的 ERC20代币
译文出自:登链翻译计划[1] 译者:Tiny熊[2] 解锁消耗到了大量的 gas 每个人都在谈论 “无gas” 的以太坊交易,因为没有人喜欢支付gas费用。但是以太坊网络的运行正是因为交易是付费的。那
Tiny熊
2020/09/29
3.5K0
通过链下签名授权实现更少 Gas 的 ERC20代币
解读UniSwap NFT市场协议不仅仅是聚合器
作为日交易量达 7.7 亿美元、拥有 400 多万用户的 UniSwap 来说,进军 NFT 市场赛道也意味着新一轮攻防战的开始,众多平台一时都担忧对方是否会抛出类似SudoSwap那样初始即王炸的好牌。
十四君
2023/02/20
1.4K0
解读UniSwap NFT市场协议不仅仅是聚合器
【知识】无GAS以太坊交易实现原理及源码
每个人都在讨论无gas以太坊交易,因为没有人喜欢支付gas费用。但是以太坊网络能够精准地运转恰恰是因为交易需要手续费。那么如何实现无gas交易呢?让我们一起学习无gas以太坊交易的魔法!
辉哥
2021/11/24
1.9K0
【知识】无GAS以太坊交易实现原理及源码
WETH10 - 更高效的 WETH
玩过 DEFI 的应该都知道,很多项目是通过 WETH 把以太币代币化[1],再接入到 ERC20 为主的 DEFI 生态中。
Tiny熊
2020/11/03
1.6K0
WETH10 - 更高效的 WETH
如何在去中心化交易所中(DEX)集成0x协议
什么是0x协议,它的工作机制是怎样的?这个本文将介绍0x协议,包括它的链下订单中继(撮合)、去中心化交易中继器, 以及如何在以太坊公链或私链上通过0x智能合约构建自己的去中心化交易所(DEX)。
Tiny熊
2020/08/06
2.4K0
如何在去中心化交易所中(DEX)集成0x协议
【以太坊通证标准】ERC20系列,ERC721系列,ERC865
【本文目标】 通过本文学习,了解ERC定义及知名ERC协议标准,如ERC20以及ERC223、ERC621,ERC827协议,ERC721以及 ERC875,ERC1155,ERC998协议,ERC 865等描述和定义。
辉哥
2018/08/10
1.8K0
【以太坊通证标准】ERC20系列,ERC721系列,ERC865
每周以太坊进展 2022/11/19
(编者注:本翻译不代表登链社区的立场,也不代表我们(有能力并且已经)核实所有的事实并把他的观点分离开来。)
Tiny熊
2023/01/09
6650
创建并部署ERC20代币
第一个标准由 Fabian Vogelsteller 于 2015 年 11 月以 ethereum request for Comments(ERC)引入,它被自动分配到 GitHub 第 20 个议题,所以叫“ERC20 代币”。目前绝大多数代币都基于 ERC20 标准。ERC20 后来变成了以太坊改进提案 20(EIP-20),但是大部分仍然使用它最初的名字,ERC20。
Tiny熊
2022/04/08
1.5K0
创建并部署ERC20代币
【区块链技术工坊34期】王登辉:以太坊通证协议标准及应用场景
2)议题: 通过本次技术分析,可以了解以太坊的ERC定义及知名ERC协议标准,如同质化通证系列ERC20以及ERC223协议; 非同质化系列ERC721以及 ERC875,ERC1155协议;STO标准半同质化系列ERC1400系列协议。
辉哥
2019/03/15
8700
【区块链技术工坊34期】王登辉:以太坊通证协议标准及应用场景
ERC777 功能型代币(通证)最佳实践
想必很多同学都已经使用过ERC20 创建过代币[1],或许已经被老板要求在ERC20代币上实现一些附加功能搞的焦头烂额,如果还有选择,一定要选择 ERC777 。
Tiny熊
2019/09/30
1.3K0
ERC-777标准规范
在经典的ERC-20场景中,如果用户想要授权给第三方账户或者智能合约进行转账操作,那么需要通过两个事务来完成整个转账的操作,在这里需要注意的是在授权是需要指定对应的amount数量,那么当每次进行授权转账时都需要进行一次查询或者让A用户再次授权给B用户:
Al1ex
2021/07/21
1.2K0
ERC-777标准规范
在经典的ERC-20场景中,如果用户想要授权给第三方账户或者智能合约进行转账操作,那么需要通过两个事务来完成整个转账的操作,在这里需要注意的是在授权是需要指定对应的amount数量,那么当每次进行授权转账时都需要进行一次查询或者让A用户再次授权给B用户:
Al1ex
2021/07/16
1.7K0
ERC-777标准规范
ERC-20标准规范
ERC-20为以太坊智能合约提供了一套编写规范,而IERC-20则规定了一个Token需要实现的基本接口,本篇文章将对此进行解读。
Al1ex
2021/03/23
2.5K0
ERC-20标准规范
使用Uniswap V2部署自己的去中心化交易所
Dapp链接:https://www.chainpip.com/dapp-view/6724
fingernft
2022/10/24
1.4K0
使用Uniswap V2部署自己的去中心化交易所
剖析DeFi交易产品之Uniswap:V2中篇
上篇我们主要讲了 UniswapV2 整体分为了哪些项目,并重点讲解了 uniswap-v2-core 的核心代码实现。这篇我们来看看 uniswap-v2-periphery。
Keegan小钢
2021/10/08
2.8K0
ERC777的特点
ERC777[2] 与 ERC20 都是一类的合约,都是fungible tokens的一种标准。并且 ERC777 是对 ERC20 兼容的,ERC20 中的相关操作在 ERC777 中都能够实现,并且 ERC777 还提供了更加复杂的操作,还在 ERC20 的不足的地方进行了改善提升。可以说ERC777 是在 ERC20 的基础上进行的升级改造,但是由于 ERC777 出现的时间较晚,现在市场上主流的货币还是使用的 ERC20,但是这并不能否定 ERC777 相比于 ERC20 更高效与更安全。详情可以查看https://docs.openzeppelin.com/contracts/4.x/erc777.
Tiny熊
2023/01/09
5380
每周以太坊进展2022/7/16
(编者注:本翻译不代表登链社区的立场,也不代表我们(有能力并且已经)核实所有的事实并把他的观点分离开来。)
Tiny熊
2022/11/07
5520
安全的处理 ERC20 转账(解决非标准 ERC20 问题)
你可能认为在 ERC-20 调用几个函数非常简单,对吗?很不幸,不是的。有些事情我们必须要考虑,而且还可能出现一些很常见的问题。
Tiny熊
2021/10/13
1.9K0
创建一个ERC721标准的NFT
这是一个符合ERC721标准的NFT合约代码,其中包括了几个常用的标准接口和合约,下面是个合约的具体信息:
jetsan
2022/09/27
8610
创建一个ERC721标准的NFT
相关推荐
Uniswap V2 源码学习 (四). 签名和路由
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档