如何在合约中集成 Uniswap v3
来源:未知 时间:2021-06-06 08:02 浏览量:
分享至

在你的函数的开头做一个简单的检查就足够了。现在,对于 convertEthToExactDai 函数,它将看起来像这样的东西。

这里有几件事情需要解读。

  • Swap Router:SwapRouter 将是一个由 Uniswap 提供的包装合约,它有几个安全机制和便利功能。你可以使用 ISwapRouter(0xE592427A0AEce92De3Edee1F18E0157C05861564) 为任何主网或测试网实例化它。接口代码可以在这里 [9] 找到。

  • WETH: 你可能注意到,我们在这里使用 ETH。在 Uniswap 中,不再有直接的 ETH 对,所有的 ETH 必须首先转换为 WETH (这是 ETH 包裹的 ERC-20)。在我们的案例中,这是由 SwapRouter 完成的。

  • exactOutputSingle [10]:该函数可用于使用 ETH 并接收准确的代币数量。任何剩余的 ETH 将被退还,但不是自动! 我自己没有第一时间意识到这一点,ETH 最后在路由器合约中。所以不要忘记在兑换后调用 uniswapRouter.refundETH()! 并确保你的合约中有一个回退函数来接收 ETH:receive() payable external {}deadline 参数控制交易有效期。确保从你的前端传递这个 UNIX 时间戳,不要在合约内使用 now

  • Refund(退款):一旦交易完成,我们可以将任何剩余的 ETH 返还给用户。这里将发送合约中的所有 ETH,所以如果你的合约可能因为其他原因有 ETH 余额,请确保改变这一点。

  • Fee (费用):这是一个不稳定的,但很受欢迎的货币对,所以我们在这里使用的费用是 0.3%(见上面的费用部分)。

  • sqrtPriceLimitX96。可用于确定互换不能超过的池子价格的限制。如果你把它设置为 0,它就被忽略了。

在前台使用 V3

我们现在遇到的一个问题是,当用户调用支付函数并想用 ETH 支付时,不知道他需要多少 ETH。我们可以使用 quoteExactOutputSingle[11] 函数来精确计算:

但是请注意,我们没有把它声明为视图函数,但是不要在链上调用这个函数。尽管它可以作为一个视图函数来调用的,但它会采用非视图方式(底层)来获得计算结果。由于 Solidity 的特性,所以这里也不可能将它本身声明为一个视图函数,仅能使用场景如 Web3 的 call()[12] 功能来读取前端的结果。

现在我们可以在前端调用 getEstimatedETHforDAI。为了确保我们发送了足够的 ETH,并且交易不会被退回,我们可以将估计的 ETH 数量增加一点。

如果没有直接兑换流动池怎么办?

在这种情况下,你可以使用 exactInput[13] 和 exactOutput[14] 函数,它以 path 为参数。这个路径是代币地址的字节编码数据(为了 Gas 效率而编码)。

任何兑换都需要有一个开始和结束的路径。虽然在 Uniswap 中,你可以有代币 1 到代币 2 的兑换,但不一定能保证这样一个池子真的存在。但是,只要你能找到一条路径,你仍然可以交易它们,例如,Token1 → Token2 → WETH → Token3。在这种情况下,你仍然可以用 Token1 换 Token3,只是比直接兑换要多花一点 gas。

在下边你可以看到 Uniswap 示例代码,了解如何在前端计算这个路径:

为 Remix 提供完整的工作实例

这里有一个完全可用的例子,你可以直接在 Remix 上使用。它允许你用 ETH 交易 Multi-collaterized Kovan DAI[15],它还包括 exactOutputSingle[16] 的替代方案,即 exactInputSingle[17],允许你用 ETH 换取多少 DAI,你就能得到多少。

ExactInput 和 ExactOutput 的区别

一旦你执行这些函数并在 Etherscan 中查看它们,区别就会立即变得很明显。这里我们是用 exactOutput 进行交易。我们提供 1 个 ETH,希望收到 100 个 DAI 作为回报。任何多余的 ETH 都会退还给我们。

以准确的 DAI 购买

而下面,我们正在使用 exactInput 进行交易。我们提供 1 个 ETH,并希望得到多少 DAI,而这恰好是 196 个 DAI。

用精确的 ETH 购买

请注意,如果你困惑为什么价格会如此不同,这是测试网的一个小池子,第一个交易严重影响了池子里的价格。没有多少人在测试网中进行套利交易 :)

参考资料

[1]

登链翻译计划 :https://github.com/lbc-team/Pioneer

[2]

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

[3]

Tiny 熊 :https://learnblockchain.cn/people/15

[4]

Uniswap:https://uniswap.exchange/

[5]

一篇文章 :https://soliditydeveloper.com/uniswap2

[6]

v3 自 2021 年 5 月 5 日起在主网上运行 :https://uniswap.org/blog/launch-uniswap-v3/

[7]

文件 :https://docs.uniswap.org/

[8]

白皮书 :https://uniswap.org/whitepaper-v3.pdf

[9]

这里 :https://github.com/Uniswap/uniswap-v3-periphery/blob/main/contracts/interfaces/ISwapRouter.sol

[10]

exactOutputSingle:https://docs.uniswap.org/reference/periphery/interfaces/ISwapRouter#exactoutputsingle

[11]

quoteExactOutputSingle:https://docs.uniswap.org/reference/periphery/interfaces/IQuoter#quoteexactoutputsingle

[12]

call():https://web3js.readthedocs.io/en/v1.3.4/web3-eth-contract.html#methods-mymethod-call

[13]

exactInput:https://docs.uniswap.org/reference/periphery/interfaces/ISwapRouter#exactinput

[14]

exactOutput:https://docs.uniswap.org/reference/periphery/interfaces/ISwapRouter#exactoutput

[15]

Multi-collaterized Kovan DAI:https://oasis.app/borrow"如何在合约中集成 Uniswap v3" loading="lazy" src="/uploads/allimg/210606/0P2455W0-0.jpg"/>