沈阳外贸网站制作公司,网站运营的案例,如何创建一个自己公司网站,网站建设相关参考资料library contract 在 Solidity 中#xff0c;库是一种无状态合约#xff08;即它没有可变状态#xff09;#xff0c;它实现了一组可被其他合约使用的函数--这是库的主要目的。与合约不同#xff0c;库没有状态#xff1a;它们的函数通过 DELEGATECALL 在调用者的状态下…library contract 在 Solidity 中库是一种无状态合约即它没有可变状态它实现了一组可被其他合约使用的函数--这是库的主要目的。与合约不同库没有状态它们的函数通过 DELEGATECALL 在调用者的状态下执行。但与合约一样库也必须部署后才能使用。幸运的是Forge 支持自动链接库我们不需要在测试中部署库这让我们的工作变得更轻松。
library ZuniswapV2Library {error InsufficientAmount();error InsufficientLiquidity();function getReserves(address factoryAddress,address tokenA,address tokenB) public returns (uint256 reserveA, uint256 reserveB) {(address token0, address token1) _sortTokens(tokenA, tokenB);(uint256 reserve0, uint256 reserve1, ) IZuniswapV2Pair(pairFor(factoryAddress, token0, token1)).getReserves();(reserveA, reserveB) tokenA token0? (reserve0, reserve1): (reserve1, reserve0);}... 这是一个高级函数它可以获取任意配对的reserve。 函数的第一步是token地址排序--当我们想通过token地址查找pair地址时总是要这样做。这就是我们下一步要做的事情有了factory地址和排序过的token地址我们就能获得pair地址--我们接下来会看看 pairFor 函数。 请注意在返回之前我们已经对储备进行了排序我们希望按照token地址指定的顺序返回它们 现在让我们来看看 pairFor 函数
function pairFor(address factoryAddress,address tokenA,address tokenB) internal pure returns (address pairAddress) { 该函数用于通过factory地址和token地址查找pair地址。最直接的方法是从factory合约中获取配对地址例如
ZuniswapV2Factory(factoryAddress).pairs(address(token0), address(token1)) 但这样做会产生外部调用从而使函数的运行成本增加。 Uniswap 使用的是更先进的方法我们可以从 CREATE2 操作码的确定性地址生成中获的启发。
(address token0, address token1) sortTokens(tokenA, tokenB);pairAddress address(uint160(uint256(keccak256(abi.encodePacked(hexff,factoryAddress,keccak256(abi.encodePacked(token0, token1)),keccak256(type(ZuniswapV2Pair).creationCode)))))); 这段代码生成地址的方式与 CREATE2 相同。 1、第一步是对token地址进行排序。还记得 createPair 函数吗我们使用排序过的令牌地址作为盐。 2、接下来我们构建一个字节序列其中包括 0xff - 第一个字节有助于避免与 CREATE 操作码发生碰撞。(更多详情请参见 EIP-1014。 factoryAddress - 用于部署配对的工厂。 salt - 已排序和散列的token地址。 一对合约字节码的哈希值 - 我们对 creationCode 进行哈希处理以获得该值。 3、然后对字节序列进行散列keccak256并转换为地址字节-uint256-uint160-地址。 整个过程在 EIP-1014 中定义并在 CREATE2 操作码中实现。我们要做的就是在 Solidity 中重新实现地址生成 最后我们来到引用函数。
function quote(uint256 amountIn,uint256 reserveIn,uint256 reserveOut) public pure returns (uint256 amountOut) {if (amountIn 0) revert InsufficientAmount();if (reserveIn 0 || reserveOut 0) revert InsufficientLiquidity();return (amountIn * reserveOut) / reserveIn;} 如前所述该函数根据输入量和配对储备计算输出量。这样我们就可以知道用特定数量的token A 换取多少token B。在交换中使用的是基于恒积公式的公式。