Say I have a contract MyToken.sol which has already been deployed to a public Ethereum network. Its source is maintained in an external repository and is included in my package.json file so that it falls under the node_modules/ directory. I create my own contract MyContract.sol in the local project's contracts/ directory. In order to prevent compiling the entire contract (and its imported contracts) of MyToken.sol, I use an interface IMyToken.sol in my local project to give MyContract.sol only the functions that it needs from MyToken.sol. This is also beneficial to prevent Truffle from displaying compiler warnings for older contracts which have already been deployed.

The project structure is as follows:

    +- contracts
    |     |
    |     +- interfaces
    |     |     |
    |     |     +- IMyToken.sol
    |     |
    |     +- MyContract.sol
    +- node_modules
          +- my_token
                +- contracts
                      +- MyToken.sol

The source of MyContract.sol is similar to the following:

pragma solidity ^0.4.24;

import "interfaces/IMyToken.sol";

contract MyContract {
  IMyToken token = IMyToken(0x...);

Compiling this locally works perfectly fine. I can even deploy it to a network where MyToken is already deployed and interact with it as expected. However, for local testing, I need to deploy my own instance of MyToken.sol, but I want to avoid including it in my project. Since the actual MyToken.sol is not located within my project's contracts/ directory, Truffle does not generate artifacts for it. Therefore, the following does not work for any migrations script:

var MyToken = artifacts.require("../node_modules/my_token/contracts/MyToken.sol");

My question is: What is the best practice for generating artifacts in Truffle for contracts which reside outside of the local project?

To give one possible solution (which I'm not too fond of), I can create a contracts/lib/ directory and store a base contract which imports from the node_modules/ directory. For example:

pragma solidity ^0.4.24;

import "my_token/contracts/MyToken.sol";

The only problem that I have with this solution is I still get all of the old compiler warnings because MyToken was deployed with an older Solidity version.


1 Answer 1


In order to deploy a different project, you need its json compiler output, within this file you'd find the compiled bytecode which can then be deployed locally for testing.

Doing so using ethers.js is pretty easy. For instance to deploy the WETH native token wrapper you first install npm i -D canonical-weth, it'll then reside in your node_modules dir, now use it the following way in your test.js -

const compiledWETH = require("canonical-weth/build/contracts/WETH9.json");
const factoryWETH = new ethers.ContractFactory(compiledWETH.abi, compiledWETH.bytecode, ownerAccount);
const WETH = await factoryWETH.deploy();

after that you'll have WETH deployed at WETH.address, ready for your tests.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.