安装@openzeppelin/contracts后SafeMath合约无法导入是什么原因
问题描述
- 正在使用Ethernaut平台提供的CoinFlip练习合约,已执行
sudo npm i @openzeppelin/contracts命令安装依赖,合约代码如下:
pragma solidity 0.6.0; import "@openzeppelin/contracts/math/SafeMath.sol"; contract CoinFlip { using SafeMath for uint256; uint256 public consecutiveWins; uint256 lastHash; uint256 FACTOR = 57896044618658097711785492504343953926634992332820282019728792003956564819968; constructor() public { consecutiveWins = 0; } function flip(bool _guess) public returns (bool) { uint256 blockValue = uint256(blockhash(block.number.sub(1))); if (lastHash == blockValue) { revert(); } lastHash = blockValue; uint256 coinFlip = blockValue.div(FACTOR); bool side = coinFlip == 1 ? true : false; if (side == _guess) { consecutiveWins++; return true; } else { consecutiveWins = 0; return false; } } }
- 安装依赖后编译仍报错,报错信息为:
Error: Could not find @openzeppelin/contracts/math/SafeMath.sol from any sources - 当前开发环境配置:
Truffle v5.1.39 (core: 5.1.39) Solidity - 0.6.0 (solc-js) Node v16.13.1 Web3.js v1.2.1
报错原因
两个核心问题导致编译失败:
- 直接执行
npm i @openzeppelin/contracts默认安装的是最新大版本(v4.x及以上),该版本最低要求Solidity 0.8.0,和使用的0.6.0版本不兼容;同时高版本OpenZeppelin已经调整了SafeMath的存放路径,原math/SafeMath.sol路径已不存在。 - 安装命令加了
sudo,会把依赖安装到系统全局node_modules目录,而Truffle编译时默认只会检索当前项目本地的node_modules目录,即使装对版本也可能出现找不到包的问题。
解决步骤
按顺序执行以下操作即可修复问题:
- 首先卸载当前安装的错误版本依赖,在项目根目录执行命令:
npm uninstall @openzeppelin/contracts - 安装和Solidity 0.6.0版本兼容的OpenZeppelin Contracts v3.x稳定版,执行命令:
npm install @openzeppelin/contracts@3.4.2,注意不要加sudo前缀,确保依赖安装在当前项目的本地node_modules目录下 - 安装完成后,检查本地路径
node_modules/@openzeppelin/contracts/math/SafeMath.sol是否存在,确认文件存在后重新执行truffle compile即可正常完成编译。
内容的提问来源于stack exchange,提问作者Emily Kuo
相关产品推荐
相关产品推荐

