6

I'm using truffle migrations a lot, and I would like to deploy a contract twice during my migrations. Is it possible? Nowadays, I'm using migrations like

const MyContract = artifacts.require('MyContract')

module.exports = deployer => {
  deployer.deploy(MyContract)
}

Is there any way to do something like

const MyContract = artifacts.require('MyContract')

module.exports = deployer => {
  const firstDeploy = deployer.deploy(MyContract)
  const secondDeploy = deployer.deploy(MyContract)
}

And then to fetch them easily in the rest of my application?

2 Answers 2

1

I have never tried deploying two identical contracts before, alternative approach you can take, is to make a factory contract (contract that makes contracts). See EIP20 Factory

It depends how you are using the contracts, I recommend using exploring existing migration options. For example you can pass in your contract addresses into a main contract. Technically, I think you could make two contracts exactly identical under different names. Quick and Dirty.

I think you want to have main contract to track the two identical contracts.

For example your migrations file could look like

const contractMain = artifacts.require("contractMain");
const contractCopy1 = artifacts.require("contractCopy1");
const contractCopy2 = artifacts.require("contractCopy2");
module.exports = function(deployer) {

    // Don't overwrite existing contracts.
    deployer.deploy(contractCopy1, {overwrite: false})
    deployer.deploy(contractCopy2).then(function() {
        return deployer.deploy(contractMain, contractCopy1.address,contractCopy2.address);
    });

}; 
2
  • Yup, I thought of duplicating contracts under different names, but I think it's really dirty, because I already use the Contract with a factory. The fact is that depending on the arguments given at initialization, the contract behaves differently. Which means it make it hard to test it with only one version because some things are disabled in some cases. I think I'll end up with a TestFactory only to test the contract itself.
    – ghivert
    Oct 5, 2018 at 17:44
  • You could also use remix to deploy a contract manually, and then input the address, remix.ethereum.org/#optimize=false. I'm not sure how you have set up your contracts, but if you just input an address, this should work fine. Perhaps what you want to do is deploy different versions of the same contract at the same time. If that is the case, I think ethereum doesn't overwrite the existing contract, it is still deployed, just input the old contract address, if you can find it.
    – GrandFleet
    Oct 5, 2018 at 18:30
3

It is possible to deploy multiple versions of the same contract. The issue is that Truffle assumes every contract will be deployed only once.

Depending on your use case you have a couple of workarounds.

  • Create different contracts that inherits from the same 'base' contract. This will work fine if you have only a few contracts to deploy.

    For example if you have a contract Token as base and you want to create a two instances one to manage games and other for assets. You can create TokenGames and TokenAssets.

  • Do not use Truffle deployer, and deploy manually.

    async function initContracts(param1, param2, owner) {
      const token1 = await Token.new(param1, { from: owner });
      const token2 = await Token.new(param2, { from: owner });
      return [token1, token2];
    }
    

    A problem with this approach is that you have to manage the addresses of the contracts on your own, perhaps using a configuration file.

1
  • 2
    "The issue is that Truffle assumes every contract will be deployed only once." -- deployer.deploy(Contract, ...) is meant to deploy a singleton, so it works as designed. If multiple instances are needed, then a good way as you suggest is to use Contract.new(...) and manage the multiple addresses on your own. I wouldn't use a factory contract for this, if the reason is only for working around truffles singleton feature.
    – ivicaa
    Oct 9, 2018 at 20:18

Your Answer

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

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