部署Uniswap V3遭遇Solidity编译器错误求助
问题
我正在测试网部署Uniswap V3,有两个疑惑:
- 是否必须导入并编译所有相关文件才能部署所需合约?
- 尽管已在Hardhat配置中指定多个Solidity版本,仍出现大量编译器错误,此前部署Uniswap V2时没这问题,是不是因为Solidity 0.5和0.6版本兼容性更好?
我的Hardhat配置
solidity: { compilers: [ { version: '0.5.16', settings: { optimizer: { enabled: true, runs: 200, }, }, }, { version: '0.8.0', settings: { optimizer: { enabled: true, runs: 200, }, }, }, { version: '0.8.1', settings: { optimizer: { enabled: true, runs: 200, }, }, }, { version: '0.6.6', settings: { optimizer: { enabled: true, runs: 200, }, }, }, { version: '0.7.6', settings: { optimizer: { enabled: true, runs: 200, }, }, }, ], },
编译器错误信息
Error HH606: The project cannot be compiled, see reasons below. These files import other files that use a different and incompatible version of Solidity: * contracts/periphery/interfaces/external/IWETH9.sol (=0.7.6) imports @openzeppelin/contracts/token/ERC20/IERC20.sol (^0.8.0) * contracts/periphery/interfaces/IERC20Metadata.sol (^0.7.0) imports @openzeppelin/contracts/token/ERC20/IERC20.sol (^0.8.0) * contracts/Token.sol (=0.5.16) imports @openzeppelin/contracts/token/ERC20/ERC20.sol (^0.8.0) * contracts/periphery/base/ERC721Permit.sol (=0.7.6) imports @openzeppelin/contracts/token/ERC721/ERC721.sol (^0.8.0) and @openzeppelin/contracts/utils/Address.sol (^0.8.1) These files depend on other files that use a different and incompatible version of Solidity: * contracts/periphery/SwapRouter.sol (=0.7.6) depends on @openzeppelin/contracts/token/ERC20/IERC20.sol (^0.8.0), @openzeppelin/contracts/token/ERC20/IERC20.sol (^0.8.0) and 19 other files. Use --verbose to see the full list. * contracts/periphery/V3Migrator.sol (=0.7.6) depends on @openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol (^0.8.0), @openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol (^0.8.0) and 22 other files. Use --verbose to see the full list. * contracts/periphery/NonfungiblePositionManager.sol (=0.7.6) depends on @openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol (^0.8.0), @openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol (^0.8.0) and 38 other files. Use --verbose to see the full list. * contracts/periphery/NonfungibleTokenPositionDescriptor.sol (=0.7.6) depends on @openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol (^0.8.0), @openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol (^0.8.0) and 13 other files. Use --verbose to see the full list. * contracts/periphery/libraries/PositionValue.sol (>=0.6.8 <0.8.0) depends on @openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol (^0.8.0), @openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol (^0.8.0) and 6 other files. Use --verbose to see the full list. * contracts/periphery/examples/PairFlash.sol (=0.7.6) depends on @openzeppelin/contracts/token/ERC20/IERC20.sol (^0.8.0), @openzeppelin/contracts/token/ERC20/IERC20.sol (^0.8.0) and 2 other files. Use --verbose to see the full list. * contracts/periphery/base/LiquidityManagement.sol (=0.7.6) depends on @openzeppelin/contracts/token/ERC20/IERC20.sol (^0.8.0), @openzeppelin/contracts/token/ERC20/IERC20.sol (^0.8.0) and 1 other file. Use --verbose to see the full list. These files and its dependencies cannot be compiled with your config. This can happen because they have incompatible Solidity pragmas, or don't match any of your configured Solidity compilers. * contracts/periphery/libraries/NFTDescriptor.sol * contracts/periphery/base/PeripheryPaymentsWithFee.sol * contracts/periphery/base/PeripheryPayments.sol To learn more, run the command again with --verbose Read about compiler configuration in Hardhat documentation
回答
1. 不需要编译所有文件才能部署目标合约
Hardhat默认会编译项目内所有.sol文件,但你可以通过两种方式只编译需要的部分:
- 在Hardhat配置里修改
paths.sources,指定只包含目标合约所在的目录; - 编译时用
--files参数直接指定要编译的合约文件,比如:
注意:目标合约的所有直接、间接依赖仍需能被正确编译,否则部署时会缺少必要的字节码。npx hardhat compile --files contracts/periphery/SwapRouter.sol
2. V3出现兼容性错误的核心原因
不是单纯0.5/0.6兼容性更好,而是你用的OpenZeppelin版本和Uniswap V3合约的Solidity版本不匹配:
- Uniswap V3的外围合约大多基于Solidity 0.7.6开发,但你安装的OpenZeppelin合约是0.8.x版本的。Solidity 0.7和0.8之间有大量不兼容变更(比如默认开启算术溢出检查、
uint字面量处理逻辑修改等),导致0.7版本的合约无法直接导入0.8版本的OpenZeppelin文件。 - Uniswap V2的合约主要用0.5.x和0.6.x,对应的OpenZeppelin早期版本(比如v3.x)对这些版本支持良好,且0.5到0.6的语法变更幅度远小于0.7到0.8,所以当时没触发这类冲突。
解决方法
方法一:安装Uniswap V3兼容的OpenZeppelin版本
Uniswap V3官方推荐使用OpenZeppelin v4.1.0,这个版本同时支持0.7.x和0.8.x的Solidity,能完美适配你的配置。执行以下命令安装:
npm install @openzeppelin/contracts@4.1.0
方法二:给冲突文件指定编译版本
如果不想更换OpenZeppelin版本,可以在Hardhat配置里添加overrides字段,给每个冲突的文件单独指定编译版本,让Uniswap的0.7合约用0.7.6编译,依赖的OpenZeppelin 0.8文件用0.8.0编译。示例配置:
solidity: { compilers: [/* 保留你原有的编译器配置 */], overrides: { "@openzeppelin/contracts/token/ERC20/IERC20.sol": { version: "0.8.0", settings: { optimizer: { enabled: true, runs: 200 } } }, "@openzeppelin/contracts/token/ERC721/ERC721.sol": { version: "0.8.0", settings: { optimizer: { enabled: true, runs: 200 } } } // 其他冲突的OpenZeppelin文件都按这个格式添加 } }
方法三:清理不必要的合约文件
如果项目里有不需要部署的合约(比如示例文件PairFlash.sol),可以直接删除或者移到项目外,减少编译时的冲突点。
内容的提问来源于stack exchange,提问作者defi legend
相关产品推荐
相关产品推荐

