如何在合约中集成 Uniswap v3
- 原文:https://soliditydeveloper.com/uniswap3
- 译文出自:登链翻译计划
- 译者:翻译小组
- 校对:Tiny 熊
- 本文永久链接:learnblockchain.cn/article…
如果你还不熟悉Uniswap,它是一个去中心化的交易所(DEX),依靠外部流动性提供者将代币添加到流动池配对中,用户可以直接交易这些代币。
由于它在以太坊上运行,可以交易的是以太坊ERC-20代币。每种代币都有自己的智能合约和流动资金池。Uniswap--作为完全的去中心化--对哪些代币可以添加没有限制。如果一个代币对还没有流动池合约存在,任何人都可以Uniswap的工厂创建一个,任何人都可以向池子提供流动性。每笔交易有0.3%的费用给流动性提供者作为奖励。
代币的价格是由池中的流动性决定的。例如,如果一个用户用TOKEN2购买TOKEN1,池中TOKEN1的供应将减少,而TOKEN2的供应将增加,TOKEN1的价格将增加。同样地,如果一个用户正在出售TOKEN1,TOKEN1的价格将下降。因此,代币价格总是反映了供需关系。
当然,用户不一定是人,也可以是一个智能合约。这使得可以将Uniswap添加到我们自己的合约中,为我们合约的用户增加额外的支付选项。Uniswap使这个过程非常方便,请看下面的整合方法。
之前有一篇文章讨论了Uniswap v2的新内容,现在让我们看看Uniswap v3的新内容。
提供了不同的收费等级,由资金池的风险水平决定收费等级。有三个不同的级别:
Uniswap如此受欢迎的原因之一可能是将它们整合到自己的智能合约中的非常简单。比方说,你有一个系统,用户用DAI支付。有了Uniswap,只需几行代码,你就可以增加他们也可以用ETH支付的选项。ETH可以在实际逻辑之前自动转换为DAI。它看起来像这样:
function pay(uint paymentAmountInDai) public payable {
if (msg.value > 0) {
convertEthToExactDai(paymentAmountInDai);
} else {
require(daiToken.transferFrom(msg.sender, address(this), paymentAmountInDai);
}
// do something with that DAI
...
}
在你的函数的开头做一个简单的检查就足够了。现在,对于convertEthToExactDai
函数,它将看起来像这样的东西。
function convertEthToExactDai(uint256 daiAmount) external payable {
require(daiAmount > 0, "Must pass non 0 DAI amount");
require(msg.value > 0, "Must pass non 0 ETH amount");
uint256 deadline = block.timestamp + 15; // using 'now' for convenience, for mainnet pass deadline from frontend!
address tokenIn = WETH9;
address tokenOut = multiDaiKovan;
uint24 fee = 3000;
address recipient = msg.sender;
uint256 amountOut = daiAmount;
uint256 amountInMaximum = msg.value;
uint160 sqrtPriceLimitX96 = 0;
ISwapRouter.ExactOutputSingleParams memory params = ISwapRouter.ExactOutputSingleParams(
tokenIn,
tokenOut,
fee,
recipient,
deadline,
amountOut,
amountInMaximum,
sqrtPriceLimitX96
);
uniswapRouter.exactOutputSingle{ value: msg.value }(params);
uniswapRouter.refundETH();
// refund leftover ETH to user
(bool success,) = msg.sender.call{ value: address(this).balance }("");
require(success, "refund failed");
}
这里有几件事情需要解读。
ISwapRouter(0xE592427A0AEce92De3Edee1F18E0157C05861564)
为任何主网或测试网实例化它。接口代码可以在这里找到。receive() payable external {}
。deadline
参数控制交易有效期。确保从你的前端传递这个UNIX时间戳,不要在合约内使用now
。如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!