Uniswap PoolAddress.sol类型转换错误:bytes32无法转uint160
Uniswap PoolAddress库computeAddress函数类型转换错误解决
在Hardhat项目和Remix中使用Uniswap的PoolAddress库时,调用computeAddress函数会触发类型转换错误:TypeError: Explicit type conversion not allowed from "bytes32" to "uint160"。参考Solidity文档后,尝试将bytes32转成bytes20再转uint160后错误消失,但担心这种转换会截断bytes32的部分十六进制值,想确认这是不是正确的解决方式。
原错误代码
function computeAddress(address factory, PoolKey memory key) internal pure returns (address pool) { require(key.token0 < key.token1); //*******************this is causing the error*************** pool = address( uint160( keccak256( abi.encodePacked( hex'ff', factory, keccak256(abi.encode(key.token0, key.token1, key.fee)), POOL_INIT_CODE_HASH ) ) ) ); }
修改后的代码
function computeAddress(address factory, PoolKey memory key) internal pure returns (address pool) { require(key.token0 < key.token1); pool = address( uint160( bytes20( keccak256( abi.encodePacked( hex'ff', factory, keccak256(abi.encode(key.token0, key.token1, key.fee)), POOL_INIT_CODE_HASH ) ) ) ) ); }
正确性说明
这种转换方式完全没问题,是符合以太坊合约地址生成逻辑的:
- 以太坊地址本质是**20字节(160位)**的数值,而
keccak256生成的是32字节(256位)的哈希值 - 将bytes32转成bytes20时,Solidity会自动截取哈希值的前20字节(高位部分),这正是Uniswap官方计算Pool地址的标准逻辑
- 后续转uint160再转address,就是把这20字节的数值转换成合法的以太坊地址格式
所以你修改后的代码是正确的,不存在逻辑问题,完全可以放心使用。
内容的提问来源于stack exchange,提问作者Yilmaz
相关产品推荐
相关产品推荐

