11

So I'm using truffle and I notice that I seem to be able to deploy a contract's bytecode by calling deployer.deploy(MyContract);

But I've also seen people run:

myContract = await MyContract.new();

in a unit test without ever calling deployer.deploy().

Is my understanding correct? Do these bits of code do the same thing?

Thanks!

0

4 Answers 4

5

They're both similar in that they deploy the contract. The difference is that .deploy() behaves like a singleton in that you can access the deployed instance with .deployed(). You typically use .new() in tests to avoid the possibility of any side-effects.

Here's an example:

Example.sol

pragma solidity ^0.4.23;

contract Example {
  uint256 public data;

  function set(uint256 _data) public {
    data = _data;
  }
}

Example.spec.js

const Example = artifacts.require('Example')

contract('Example', (accounts) => {
  let instance

  beforeEach('setup', async () => {
    instance = await Example.new()

    // second test will fail with `deployed()`
    //instance = await Example.deployed()
  })

  describe('test singleton', () => {
    it('should set data', async () => {
      assert.equal(await instance.data.call(), '0')
      const {receipt: {status}} = await instance.set(5)
      assert.equal(status, '0x01')
      assert.equal(await instance.data.call(), '5')
    })

    it('should not read previous data', async () => {
      // this will be `5` instead of `0` if using `deployed()`
      assert.equal(await instance.data.call(), '0')
    })
  })
})
4
  • I've been using deployed in beforeEach and I had no inconsistency issues whatsoever. Could you elaborate on what are the fundamental differences, other than the singleton aspect? Or is that it? Nov 20, 2018 at 12:19
  • @PaulBerg that's the only difference that I know of. So you're saying that using deployed in beforeEach resets the contract? I just ran a quick test and that was not the case. See my updated answer Nov 20, 2018 at 16:53
  • On a double check, no, it doesn't reset it! In my case, there's a mapping which is added a new object in beforeEach so I think that's why there are no side-effects. Nov 20, 2018 at 16:57
  • @PaulBerg makes sense Nov 20, 2018 at 16:58
4

I think the difference is that new() simply deploys a new instance of the contract. But when a contract is deployed by deployer.deploy(), the new instance is saved in the migration for later use with MyContract.deployed(), etc.

2

Both of the above functions are used to deploy the contract to the network.

deployer.deploy(myContract);

is used in our migration file.

We can deploy our own version to the network using the .new() function:

MetaCoin.new().then(function(instance) {

// do something

console.log(instance.address);

}).catch(function(err) {

// do something

});
1
  • When the test suite starts, the contract deployment code in the /migrations folder is run automatically correct? This is important for testing side effects of your deployment code.
    – emkman
    May 15, 2018 at 19:15
0

It seems reduntant because of the beforeEach and before, before already keeps it in memory as a singleton. beforeEach will create a new instance for each test. So confusing. Two ways of doing the same thing.

1
  • For some contracts it is useful to create and use multiple instances with .new(), something you can't do with .deploy().
    – Ismael
    May 13, 2021 at 3:43

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.