{"content":{"title":"EIP-1153 除了赋能 Uniswap-v4 还能做什么","body":"2023 年 6 月，Uniswap 官方发布的一篇[博客](https://blog.uniswap.org/uniswap-v4)吸引了币圈所有人的眼球。继 [Uniswap-v3](https://learnblockchain.cn/article/2302) 推出 2 年后，v4 要来了！\r\n\r\n凭借大幅的 [gas 优化](https://learnblockchain.cn/article/6570)以及全新的 [Hook](https://learnblockchain.cn/article/6636) 玩法，进一步巩固了 Uniswap 在 Dex 领域的龙头地位。\r\n\r\n但直到笔者写作日期的 10 月，都还迟迟未上线，这是为什么呢？\r\n\r\n因为它需要下次升级（坎昆升级）所引入的新字节码，具体就是 [EIP-1153](https://eips.ethereum.org/EIPS/eip-1153)\r\n\r\n## EIP-1153 干了什么事\r\n\r\n官方是这么写的\r\n\r\n> Add opcodes for manipulating state that behaves identically to storage but is discarded after every transaction.\r\n\r\n我们知道，目前在智能合约中，变量通常可以声明存储为 2 个位置 `storage` 和 `memory` :\r\n\r\n`storage` 修饰的变量是永久保存链上的，涉及 `SSTORE` 和 `SLOAD` 这两个 opcode，gas 花费很大\r\n\r\n`memory` 出现在一个函数里临时声明的变量，用完（函数执行结束）就释放了，gas 消耗小，但只是函数内可见\r\n\r\n折中一下它们两者，其实就是 EIP-1153 要做的：修改了 `storage` 变量，但最后又复原了，一套下来相当于没改。比起普通修改 `storage` 要节省很多 gas\r\n\r\n引入新的 opcode: `TSTORE` 和 `TLOAD` ，笔者预测关键字：`Transient`\r\n\r\n## 意义\r\n\r\n引入这一机制，能带来什么好处呢？\r\n\r\n在 Uniswap-v4 中，废弃了 Factory - Pair 这种模式，转而将所有币对池子都放在一个（单例）合约里，因为省去了跨合约调用，故节省了很多 gas。单例合约的实现需要依靠 EIP-1153 来记录 token balance 变化\r\n\r\n当然关于 Uniswap-v4 具体是如何运用 EIP-1153 的还需要读者自己去研究🤓\r\n\r\n### Reentrancy lock\r\n\r\n笔者在这里介绍一个很常见的应用场景 —— **ReentrancyGuard**\r\n\r\n相信稍懂些智能合约的朋友都知道“[重入攻击](https://learnblockchain.cn/article/5260)”是区块链一大经典攻击手段，ReentrancyGuard 作为 OpenZeppelin 推出一个库，能有效防止被重入。\r\n\r\n我们来看下它的核心代码：\r\n\r\n```solidity\r\nuint256 private constant NOT_ENTERED = 1;\r\nuint256 private constant ENTERED = 2;\r\n\r\nmodifier nonReentrant() {\r\n    _nonReentrantBefore();\r\n    _;\r\n    _nonReentrantAfter();\r\n}\r\n\r\nfunction _nonReentrantBefore() private {\r\n    if (_status == ENTERED) {\r\n        revert ReentrancyGuardReentrantCall();\r\n    }\r\n    _status = ENTERED;\r\n}\r\n\r\nfunction _nonReentrantAfter() private {\r\n    _status = NOT_ENTERED;\r\n}\r\n```\r\n\r\n它做的事情很简单，引入了一种“[锁](https://learnblockchain.cn/article/6375)”机制，在上下文的前后检查和修改 `_status` 的值从而防止“重入”进来\r\n\r\n那么为什么要使用 1 和 2 来做区分，而不是 True 和 False 呢，为了节省 gas，具体可以参考 [WTF-Academy](https://github.com/WTFAcademy/WTF-gas-optimization/blob/main/11_ReentrancyGuard/readme.md)\r\n\r\n然而我们可以注意到，在 `nonReentrant` 里，最开始和结束后的 ` _status` 是一样，一套下来没变，恰好符合 EIP-1153\r\n\r\n因此在坎昆升级后，将会有更节省 gas 的新版 ReentrancyGuard 出来，或者说不需要单独的库，直接自己几行代码搞定。到时会让绝大部分 DeFi 合约更节省 gas\r\n\r\n### Single transaction [ERC-20](https://eips.ethereum.org/EIPS/eip-20) approval\r\n\r\n不知道有没有其他小伙伴和笔者一样，在刚接触 Dex 的时候，被想要 Swap 却要先 Approve Token 这一操作给整懵了。更难受的是，假如你之前 approve 的数量不够，还要再 approve 一次，要知道每笔交易都要付钱啊😭；一次 approve 的数量过多，暂时花不完又会有安全问题（合约把你的 token 转走），这叫一个矛盾啊😤\r\n\r\n为了解决先 approve 再 swap 这个问题，提出了 transferFromWithPermit 这一方法，通过预先签名随后验签的方式把 approve 合并到 swap 里来从而实现“一步化”。\r\n\r\n但有个问题，假如我签名 approve 后那些 token 没用上反悔了，签名被盗取怎么办，会不会给坏人可乘之机？\r\n\r\nEIP-1153 可以带来 temporary approve 也就是在交易开始时我 approve 了，经过一系列操作，不管那些 token 用没用上，最后都恢复回去，这样是不是安全很多。\r\n\r\n将来针对此特性应该会出新的 ERC-20 Extension 估计还会对 AA 账户抽象起一定帮助。"},"author":{"user":"https://learnblockchain.cn/people/5673","address":null},"history":null,"timestamp":1697182924,"version":1}