案发现场
首次添加交易对、一直失败、但是也没提示具体的原因。到这一步就没了、由下图可知、也没看到log、由此可见第一步就失败了。
解决方案
一、添加 工厂KywFactory
添加如下
bytes32 public constant INIT_CODE_PAIR_HASH = keccak256(abi.encodePacked(type(KywPair).creationCode));
说明
:
在智能合约中添加bytes32 public constant INIT_CODE_PAIR_HASH = keccak256(abi.encodePacked(type(KywPair).creationCode));
这一行代码的主要作用是存储KywPair合约创建代码的哈希值。这一做法常见于自动化做市商(AMM)类的去中心化交易所(DEX),如Uniswap或类似的项目,目的是为了在计算流动性池(liquidity pool)的地址时使用。
这里详细解释一下:
-
创建代码的哈希值:
keccak256(abi.encodePacked(type(KywPair).creationCode))
这一表达式计算的是KywPair
合约创建时的完整字节码的哈希值。在Solidity中,type(KywPair).creationCode
直接引用了KywPair
合约的创建字节码。 -
确定性地址生成:在自动化做市协议中,流动性池的地址通常是根据特定的算法确定性生成的,这个算法通常会利用到创建代码的哈希值。通过这种方式,只要给定相同的工厂合约地址、代币A和代币B的地址,就可以始终生成相同的流动性池地址。这确保了对于每一对代币,只存在一个流动性池。
-
防止重入和攻击:使用哈希值作为计算的一部分,有助于防止恶意行为者通过不同的创建代码来创建看似相同的流动性池,从而绕过系统的设计意图或实施攻击。
-
提高效率和安全性:存储创建代码的哈希值而不是完整的代码,可以提高计算效率,同时确保在生成流动性池地址时的透明度和不可篡改性。
-
简化地址计算:在需要计算流动性池地址的场景中,可以直接使用这个预先计算好的哈希值,而不需要重新生成或查找创建代码,从而简化了计算过程并减少了计算成本。
总的来说,INIT_CODE_PAIR_HASH
常量在去中心化金融(DeFi)项目中起到关键的作用,它帮助确保了流动性池地址的一致性和安全性,同时优化了计算效率。
二、路由KywLibrary更新
// calculates the CREATE2 address for a pair without making any external callsfunction pairFor(address factory, address tokenA, address tokenB) internal pure returns (address pair) {(address token0, address token1) = sortTokens(tokenA, tokenB);pair = address(uint(keccak256(abi.encodePacked(hex'ff',factory,keccak256(abi.encodePacked(token0, token1)),hex'c21238f28fb49774a7b7d0671f8c4e909b72b25023105d7e07ea2507b6fa3974' // init code hash))));
把INIT_CODE_PAIR_HASH 替换这个
在Swap的智能合约中,pairFor
函数用于根据给定的工厂合约地址和两个代币地址生成流动性对(liquidity pair)的地址。这个生成的地址是固定的,只要输入的参数相同,每次调用都会得到同一个结果。这种方法确保了每次创建流动性对时,如果已经存在一个具有相同代币组合的流动性对,就不会重复创建。
hex'c21238f28fb49774a7b7d0671f8c4e909b72b25023105d7e07ea2507b6fa3974'
这个十六进制字符串代表了流动性对合约的初始化代码的哈希值。在PancakeSwap的上下文中,这通常是PancakePair
合约的创建代码的Keccak256哈希值。
这个哈希值在计算流动性对地址的过程中扮演着重要角色,因为它帮助确保了生成的地址与特定的工厂合约、代币组合以及初始化代码相对应。具体来说,它的作用是:
-
确保唯一性:由于哈希函数的性质,即使微小的变化也会导致完全不同的哈希值。因此,不同的代币组合和初始化代码将产生不同的流动性对地址,即使工厂合约地址相同。
-
确定性地址生成:使用哈希函数和固定的输入参数,可以计算出一个确定性的流动性对地址。这对于避免重复创建同样的流动性对非常关键。
-
安全性:哈希函数的使用增加了攻击者预测或操纵流动性对地址的难度,从而提高了系统的安全性。
-
初始化代码的绑定:将初始化代码的哈希值作为输入之一,确保了生成的流动性对地址与特定的初始化代码紧密绑定,这样就不可能用一个不同的初始化代码来创建一个看似相同的流动性对。
因此,hex'c21238f28fb49774a7b7d0671f8c4e909b72b25023105d7e07ea2507b6fa3974'
的存在是为了确保流动性对地址的生成既具有确定性又具有安全性,同时与特定的初始化代码相绑定。在实际的代码中,这个哈希值应当是PancakePair
合约创建代码的准确哈希值,用于生成流动性对地址。