Uniswap V3代码解析:7个实用合约开发技巧

从 Uniswap 代码中学到的合约开发小技巧

最近在编写去中心化交易所开发教程时,参考了 Uniswap V3 的代码实现,学到了许多宝贵的知识点。作为一名之前只开发过简单 NFT 合约的开发者,这次尝试 Defi 合约开发让我有了不少新的收获。相信这些小技巧对想要学习合约开发的新手会很有帮助。

接下来让我们一起来看看这些实用的开发技巧,其中有些甚至可以称得上是奇技淫巧。

Web3 新手系列:我从 Uniswap 代码中学到的合约开发小技巧

可预测的合约部署地址

通常部署合约得到的是一个看似随机的地址,因为与 nonce 相关,所以合约地址难以预测。但在某些情况下,我们需要通过交易对和相关信息推断出合约地址,比如判断交易权限或获取池子地址等。

Uniswap 通过添加 salt 参数使用 CREATE2 方式创建合约,使得创建的合约地址可预测。地址生成逻辑为:新地址 = hash("0xFF",创建者地址, salt, initcode)。

Web3 新手系列:我从 Uniswap 代码中学到的合约开发小技巧

善用回调函数

Solidity 中合约之间可以互相调用。在某些场景下,A 调用 B 的方法,B 在被调用的方法中回调 A 是很有用的。

Uniswap 中,调用 UniswapV3Pool 合约的 swap 方法交易时,它会回调 swapCallback,回调会传入计算出的本次交易实际需要的 Token。调用方需要在回调中将交易所需 Token 转入 UniswapV3Pool,而不是将 swap 方法拆分为两部分让调用方调用。这确保了 swap 方法的安全性,保证整个逻辑被完整执行,无需繁琐的变量记录来确保安全性。

用异常传递信息,用 try catch 实现交易预估

Uniswap 的某些合约中,将 UniswapV3Pool 的 swap 方法用 try catch 包裹执行。这是为了模拟 swap 方法来预估交易所需 Token。由于预估时不会实际产生 Token 交换,所以会报错。Uniswap 通过在交易回调函数中抛出特殊错误,然后捕获该错误,从错误信息中解析出所需信息。

这种方法看似有些取巧,但很实用。无需为预估交易需求改造 swap 方法,逻辑也更简单。

Web3 新手系列:我从 Uniswap 代码中学到的合约开发小技巧

用大数解决精度问题

Uniswap 代码中有大量计算逻辑,如根据当前价格和流动性计算交换的 Token。为避免除法操作导致精度损失,计算过程中经常使用 << FixedPoint96.RESOLUTION 操作,即左移 96 位,相当于乘以 2^96。左移后再进行除法运算,在正常交易不溢出的情况下保证精度。

虽然理论上仍会有精度损失,但通常只是最小单位的损失,可以接受。

用 Share 方式计算收益

Uniswap 中需要记录 LP(流动性提供者)的手续费收益。显然不能在每次交易时都给每个 LP 记录各自的手续费,这会消耗大量 Gas。

Uniswap 的解决方案是在 Position 结构体中定义 feeGrowthInside0LastX128 和 feeGrowthInside1LastX128,记录每个头寸上次提取手续费时每个流动性应得的手续费。

简而言之,只需记录总手续费和每个流动性应分配的手续费即可。LP 提取手续费时,根据持有的流动性计算可提取的手续费。这类似于持有公司股票,提取股票收益时只需知道公司历史每股收益和上次提取时的收益。

Web3 新手系列:我从 Uniswap 代码中学到的合约开发小技巧

不是所有信息都需要从链上获取

链上存储相对昂贵,并非所有信息都需要上链或从链上获取。例如,Uniswap 前端网站调用的许多接口是传统 Web2 接口。

交易池列表、交易池信息等可存储在普通数据库中,有些可能需要定期从链上同步,但无需实时调用链或节点服务提供的 RPC 接口获取相关数据。

当然,关键交易必须在链上进行。

学会合约拆分,利用已有标准合约

一个项目可能包含多个实际部署的合约。即使实际部署只有一个合约,我们也可以通过继承方式将合约拆分为多个合约来维护。

例如,Uniswap 中的某些合约继承了多个合约。在实现时,直接使用了 @openzeppelin/contracts/token/ERC721/ERC721.sol 合约,这样既方便通过 NFT 方式管理头寸,又可以利用已有标准合约提高开发效率。

总结

亲自动手开发比阅读文章更能加深理解。尝试实现一个简易版去中心化交易所的过程能让你更深入理解 Uniswap 的代码实现,也能学习到更多实际项目中的知识点。

Web3 新手系列:我从 Uniswap 代码中学到的合约开发小技巧

此页面可能包含第三方内容,仅供参考(非陈述/保证),不应被视为 Gate 认可其观点表述,也不得被视为财务或专业建议。详见声明
  • 赞赏
  • 4
  • 分享
评论
0/400
论坛潜水怪vip
· 23小时前
大佬可否细说这部分技巧
回复0
熊市种菜人vip
· 07-09 08:14
小菜鸟,先从炼丹做起
回复0
难道我又错过空投vip
· 07-09 08:10
又要开卷了?刚卷nft完还不够
回复0
Web3教育家vip
· 07-09 07:53
好的同学们,让我快速讲解一下...
查看原文回复0
交易,随时随地
qrCode
扫码下载 Gate APP
社群列表
简体中文
  • 简体中文
  • English
  • Tiếng Việt
  • 繁體中文
  • Español
  • Русский
  • Français (Afrique)
  • Português (Portugal)
  • Bahasa Indonesia
  • 日本語
  • بالعربية
  • Українська
  • Português (Brasil)