网站开发及维护费用,wordpress新数据库,桂林软件开发,个人简历在线填写电子版最初的router合约实现了许多不同的交换方式。我们不会实现所有的方式#xff0c;但我想向大家展示如何实现倒置交换#xff1a;用未知量的输入Token交换精确量的输出代币。这是一个有趣的用例#xff0c;可能并不常用#xff0c;但仍有可能实现。 
GitHub - XuHugo/solidit…        最初的router合约实现了许多不同的交换方式。我们不会实现所有的方式但我想向大家展示如何实现倒置交换用未知量的输入Token交换精确量的输出代币。这是一个有趣的用例可能并不常用但仍有可能实现。 
GitHub - XuHugo/solidityproject: DApp go go go  让我们回到交换公式 (xrΔx)(y−Δy)xy 现在我们要找到的不是 Δy而是 Δx我们知道想要得到的输出Token的确切数量但不知道需要提供多少输入Token。 同样在应用基本的代数运算后我们可以得到 同样这是一个考虑到产出量Δy和费用 r 的储备金x/y关系式。 现在我们就可以实现这一公式 
function getAmountIn(uint256 amountOut,uint256 reserveIn,uint256 reserveOut) public pure returns (uint256) {if (amountOut  0) revert InsufficientAmount();if (reserveIn  0 || reserveOut  0) revert InsufficientLiquidity();uint256 numerator  reserveIn * amountOut * 1000;uint256 denominator  (reserveOut - amountOut) * 997;return (numerator / denominator)  1;} 一切都很清楚除了最后的结果多了一个 1 ,为什么会这样原因在于Solidity 中的除法即整除会将结果向下舍入这意味着结果会被截断。在计算输入金额时我们希望保证计算出的金额能达到要求的输出金额。如果结果被截断输出的金额就会稍小。 接下来我们需要 getAmountsIn 函数 
function getAmountsIn(address factory,uint256 amountOut,address[] memory path) public returns (uint256[] memory) {if (path.length  2) revert InvalidPath();uint256[] memory amounts  new uint256[](path.length);amounts[amounts.length - 1]  amountOut;for (uint256 i  path.length - 1; i  0; i--) {(uint256 reserve0, uint256 reserve1)  getReserves(factory,path[i - 1],path[i]);amounts[i - 1]  getAmountIn(amounts[i], reserve0, reserve1);}return amounts;} 它复制了 getAmountsOut但有一个显著的变化遍历路径的顺序颠倒了。由于我们知道输出金额并希望找到输入金额因此我们从路径的末尾开始以相反的顺序将输入金额填入金额数组。 高级交换函数看起来也很熟悉 
function swapTokensForExactTokens(uint256 amountOut,uint256 amountInMax,address[] calldata path,address to) public returns (uint256[] memory amounts) {amounts  ZuniswapV2Library.getAmountsIn(address(factory),amountOut,path);if (amounts[amounts.length - 1]  amountInMax)revert ExcessiveInputAmount();_safeTransferFrom(path[0],msg.sender,ZuniswapV2Library.pairFor(address(factory), path[0], path[1]),amounts[0]);_swap(amounts, path, to);} 它与我们之前实现的 swap 函数几乎完全相同但它调用的是 getAmountsIn。同样有趣的是即使金额是输入的我们也可以使用相同的 _swap 函数。