I’m trying to compile a smart contract TestMinter.sol that inherits from ERC20PresetMinterPauser.sol using the @openzeppelin/contracts library and Truffle. TestMinter.sol seems to import the ERC20PresetMinterPauser.sol correctly using
But then when ERC20PresetMinterPauser.sol tries to import I get a File import callback not supported error:
$ truffle compile
Compiling your contracts...
===========================
> Compiling ./contracts/Migrations.sol
> Compiling ./contracts/TestMinter.sol
> Compiling ./node_modules/@openzeppelin/contracts/GSN/Context.sol
> Compiling ./node_modules/@openzeppelin/contracts/access/AccessControl.sol
> Compiling ./node_modules/@openzeppelin/contracts/math/SafeMath.sol
> Compiling ./node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol
> Compiling ./node_modules/@openzeppelin/contracts/token/ERC20/ERC20Burnable.sol
> Compiling ./node_modules/@openzeppelin/contracts/token/ERC20/ERC20Pausable.sol
> Compiling ./node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol
> Compiling ./node_modules/@openzeppelin/contracts/utils/Address.sol
> Compiling ./node_modules/@openzeppelin/contracts/utils/EnumerableSet.sol
> Compiling ./node_modules/@openzeppelin/contracts/utils/Pausable.sol
> Compiling node_modules/@openzeppelin/contracts/presets/ERC20PresetMinterPauser.sol
CompileError: node_modules/@openzeppelin/contracts/presets/ERC20PresetMinterPauser.sol:5:1: ParserError: Source "node_modules/@openzeppelin/contracts/access/AccessControl.sol" not found: File import callback not supported
import "../access/AccessControl.sol";
^-----------------------------------^
,node_modules/@openzeppelin/contracts/presets/ERC20PresetMinterPauser.sol:6:1: ParserError: Source "node_modules/@openzeppelin/contracts/GSN/Context.sol" not found: File import callback not supported
import "../GSN/Context.sol";
^--------------------------^
,node_modules/@openzeppelin/contracts/presets/ERC20PresetMinterPauser.sol:7:1: ParserError: Source "node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol" not found: File import callback not supported
import "../token/ERC20/ERC20.sol";
^--------------------------------^
,node_modules/@openzeppelin/contracts/presets/ERC20PresetMinterPauser.sol:8:1: ParserError: Source "node_modules/@openzeppelin/contracts/token/ERC20/ERC20Burnable.sol" not found: File import callback not supported
import "../token/ERC20/ERC20Burnable.sol";
^----------------------------------------^
,node_modules/@openzeppelin/contracts/presets/ERC20PresetMinterPauser.sol:9:1: ParserError: Source "node_modules/@openzeppelin/contracts/token/ERC20/ERC20Pausable.sol" not found: File import callback not supported
import "../token/ERC20/ERC20Pausable.sol";
^----------------------------------------^
Compilation failed. See above.
at run (/home/contooter/.npm-global/lib/node_modules/truffle/build/webpack:/packages/compile-solidity/run.js:52:1)
at Object.sourcesWithDependencies (/home/contooter/.npm-global/lib/node_modules/truffle/build/webpack:/packages/compile-solidity/index.js:107:56)
at necessary (/home/contooter/.npm-global/lib/node_modules/truffle/build/webpack:/packages/compile-solidity/index.js:69:1)
at /home/contooter/.npm-global/lib/node_modules/truffle/build/webpack:/packages/workflow-compile/index.js:33:1
at async Promise.all (index 0)
at compile (/home/contooter/.npm-global/lib/node_modules/truffle/build/webpack:/packages/workflow-compile/index.js:23:1)
at Object.compile (/home/contooter/.npm-global/lib/node_modules/truffle/build/webpack:/packages/workflow-compile/index.js:66:45)
Truffle v5.1.57 (core: 5.1.57)
Node v14.15.1
Environment
Truffle v5.1.57 (solc 0.6.2)
Node v14.15.1 @openzeppelin/contracts 3.3.0
Linux Mint 20
I could probably do a workaround and change all the smart contracts import paths to full paths but I rather not mess around with the preconfigured contracts from OZ because of security reasons.
I'm facing the same issue. When i deploy contracts, all imports work fine but i'm trying to generate the bytecode and ABI using solc package but in this way my import files are not working.
I've tried in both ways by defining path of node_modules and with defining path. Getting error in both cases.
Why not import "@openzeppelin/contracts/token/ERC721/ERC721.sol"?
I'd strongly recommend to follow @Skyge's advice and not import from npm packages using paths starting with ../node_modules/. I think it will not even work in latest Truffle now that imports from absolute locations are disallowed (see https://github.com/trufflesuite/truffle/pull/4190). Always use @openzeppelin/contracts/... form for importing from OZ.
You might get away with using ../node_modules/ with solc directly if you consistently use only that form but mixing different forms can backfire horribly and give you weird errors. For example if you import @openzeppelin/contracts/token/ERC721/ERC721.sol in one place and then ../node_modules/@openzeppelin/contracts/token/ERC721/ERC721.sol in another, the compiler will see two different contracts called ERC721. If you then try to use various contracts importing them in the same file you will get errors about stuff being already declared.
Can you describe it in more detail? Maybe post a small code snippet that does not compile for you (along with paths you're using)? If it's broken, I'd like to get it fixed in the compiler. And if it's not, I can explain why it does not work and how to use it properly.
I mean, I'd understand if importing from @openzeppelin/ did not work for you and importing from ../node_modules/@openzeppelin/ did. But you seem to be using both in your screenshot.
solc when invoked on the CLI indeed won't on its own import from @openzeppelin/ since it's a feature of frameworks like Truffle that find stuff inside node_modules/ and make it available in Standard JSON input under the package name. If you have node_modules/ in your project directory and you use --base-path, you can import with ../node_modules/ (or even just node_modules/ because that directory is now at the VFS root) but imports from @openzeppelin/ will not work unless you actually have that directory directly inside the base path. A feature that will make it possible to import from @openzeppelin/ will very likely land in the next release of the compiler (https://github.com/ethereum/solidity/issues/11409). Until then I think the best workaround if you want your code to compile both with frameworks and directly with the compiler is to use import remapping (i.e. add @openzeppelin=node_modules/@openzeppelin to the command).