'zos create' for specific contract deploys every contract once again, failing with "check your gas limit" then

I'm curious why zos create MyContract re-deploys those contracts that have been already deployed, created and initialized before.

I have first deployed, created and initialized my Token Contract:

zos create NCDToken --network ropsten --init initialize --args x,y,z

Then I started to deploy my TokenSale contract, which contains a reference to the Token contract address in order to mint tokens:

zos create NCDTokenSale --network ropsten --init initialize --args 0x2353xxxx

But this is also redeploying my Token contract again:

✓ Contract NCDToken deployed
✓ Contract NCDTokenSale deployed
⠋ Validating and deploying contract TokenVesting

Is this caused by the dependency, as the token address is an argument in the initialize-method of TokenSale-contract?

Furthermore, all contracts have been already deployed earlier, so another deployment is not necessary actually.

At the end it fails with gas limit...

✓ Contract NCDToken deployed
✓ Contract NCDTokenSale deployed
✓ Contract TokenVesting deployed
All contracts have been deployed
:heavy_multiplication_x: Creating instance for contract at 0x1263Bd5D6F0b7a0CAA4925B67ffac072070193ff and calling 'initialize' with:

  • owner (address): "0x2353e45fF9613cFB05CC797E15cC37fd0d7F9658"
  • openingTime (uint256): "1561886117"
  • closingTime (uint256): "1562284800"
  • token (address): "0xb11d2ca96CE8C0923868E9E662A8c65dbE4E0afd"

The contract code couldn't be stored, please check your gas limit.

Is it somehow possible to create only one instance with zos create without affecting and redeploying other contracts as well?

1 Like

It seems that the handling of the argument of the contracts name is misleading here.

using just zos create ---network ropsten let’s me select the contract via CLI and is deploying then only this specific contract without re-deploying every other contract once more.

1 Like

Hi @itinance

I attempted to reproduce what you saw.

I created NCDToken and this resulted in logic contracts for NCDToken, NCDTokenSale and TokenVesting being deployed along with a proxy contract for NCDToken. You can see the three logic contracts and one proxy contract in zos.ropsten.json

I assume that because NCDToken, NCDTokenSale and TokenVesting are contracts in zos.json the logic contracts get deployed when zos create is called, whilst TeamVesting logic contract does not get deployed.

$ npx zos create NCDToken --init "initialize(uint256,uint256[])" --args 0x77737a65C296012C67F8c7f656d1Df81827c9541,[0x77737a65C296012C67F8c7f656d1Df81827c9541] --network ropsten
✓ Compiling contracts with Truffle, using settings from truffle.js file
Truffle output:
 [ '0xc935f170609eb1fdc7310314509fd786cc9cc7c3' ]

Compiling your contracts...
===========================
> Compiling ./contracts/NCDToken.sol
> Compiling ./contracts/NCDTokenSale.sol
> Compiling ./contracts/TeamVesting.sol
> Compiling ./contracts/TokenVesting.sol
> Compiling ./contracts/mocks/NCDTokenSaleImpl.sol
> Compiling openzeppelin-eth/contracts/access/Roles.sol
> Compiling openzeppelin-eth/contracts/access/roles/MinterRole.sol
> Compiling openzeppelin-eth/contracts/access/roles/PauserRole.sol
> Compiling openzeppelin-eth/contracts/lifecycle/Pausable.sol
> Compiling openzeppelin-eth/contracts/math/SafeMath.sol
> Compiling openzeppelin-eth/contracts/ownership/Ownable.sol
> Compiling openzeppelin-eth/contracts/token/ERC20/ERC20.sol
> Compiling openzeppelin-eth/contracts/token/ERC20/ERC20Detailed.sol
> Compiling openzeppelin-eth/contracts/token/ERC20/ERC20Mintable.sol
> Compiling openzeppelin-eth/contracts/token/ERC20/ERC20Pausable.sol
> Compiling openzeppelin-eth/contracts/token/ERC20/IERC20.sol
> Compiling openzeppelin-eth/contracts/token/ERC20/SafeERC20.sol
> Compiling openzeppelin-eth/contracts/token/ERC20/TokenTimelock.sol
> Compiling openzeppelin-eth/contracts/utils/Address.sol
> Compiling zos-lib/contracts/Initializable.sol
> Artifacts written to /mnt/c/Users/andre/Documents/projects/forum/ncd-token/build/contracts
> Compiled successfully using:
   - solc: 0.5.8+commit.23d335f2.Emscripten.clang


[ '0xc935f170609eb1fdc7310314509fd786cc9cc7c3' ]
[ '0xc935f170609eb1fdc7310314509fd786cc9cc7c3' ]
[ '0xc935f170609eb1fdc7310314509fd786cc9cc7c3' ]
✓ Linked dependency openzeppelin-eth 2.2.0
✓ Contract NCDToken deployed
✓ Contract NCDTokenSale deployed
✓ Contract TokenVesting deployed
All contracts have been deployed
✓ Setting everything up to create contract instances
✓ Instance created at 0xAF53B91508003D6875b00Da470808f2dB53F1A5E
0xAF53B91508003D6875b00Da470808f2dB53F1A5E

I then created NCDTokenSale and this resulted in a proxy contract for NCDToken being deployed. The logic contracts had already been deployed so weren’t redeployed. You can see the additional proxy contract in zos.ropsten.json

$ npx zos create NCDTokenSale --init "initialize(address,uint256,uint256,address)" --args 0x77737a65C296012C67F8c7f656d1Df81827c9541,1562971493,1662971493,0xBc53027c52B0Ee6ad90347b8D03A719f30d9d7aB --network ropsten
✓ Compiling contracts with Truffle, using settings from truffle.js file
Truffle output:
 [ '0xc935f170609eb1fdc7310314509fd786cc9cc7c3' ]

Compiling your contracts...
===========================
> Compiling ./contracts/NCDToken.sol
> Compiling ./contracts/NCDTokenSale.sol
> Compiling ./contracts/TeamVesting.sol
> Compiling ./contracts/TokenVesting.sol
> Compiling ./contracts/mocks/NCDTokenSaleImpl.sol
> Compiling openzeppelin-eth/contracts/access/Roles.sol
> Compiling openzeppelin-eth/contracts/access/roles/MinterRole.sol
> Compiling openzeppelin-eth/contracts/access/roles/PauserRole.sol
> Compiling openzeppelin-eth/contracts/lifecycle/Pausable.sol
> Compiling openzeppelin-eth/contracts/math/SafeMath.sol
> Compiling openzeppelin-eth/contracts/ownership/Ownable.sol
> Compiling openzeppelin-eth/contracts/token/ERC20/ERC20.sol
> Compiling openzeppelin-eth/contracts/token/ERC20/ERC20Detailed.sol
✓ Instance created at 0xa16e3bA4d64404A71940681699a54626653D1312
0xa16e3bA4d64404A71940681699a54626653D1312

I didn’t get an error for gas limit, I can see that you have increased the gas limit for ropsten in truffle-config.js which I assume resolved the issue.


I created a sample project to reproduce, just deploying to a development network.

mkdir sample
cd sample
npm init -y
npm i zos
npx zos init

Create two sample contracts SampleA and SampleB

pragma solidity ^0.5.10;

contract SampleA {
}
pragma solidity ^0.5.10;

contract SampleB {
} 

Add the contracts to zos.json

npx zos add SampleA
npx zos add SampleB

Create contract SampleA.

$ npx zos create SampleA --network development
Nothing to compile, all contracts are up to date.
✓ Contract SampleA deployed
✓ Contract SampleB deployed
All contracts have been deployed
✓ Setting everything up to create contract instances
✓ Instance created at 0x8b9e409a817c7dC1a42C3DDe9E85dcBFF602c0fC
0x8b9e409a817c7dC1a42C3DDe9E85dcBFF602c0fC

This results in logic contracts for SampleA and SampleB being deployed, and a proxy for SampleA being deployed. (you can see this in zos.dev.....json)

Create contract SampleB

$ npx zos create SampleB --network development
Nothing to compile, all contracts are up to date.
All contracts are up to date
✓ Instance created at 0xcCf27643fa6C4FC844a8945b7c2F8bd562153649
0xcCf27643fa6C4FC844a8945b7c2F8bd562153649

This results in a proxy for SampleB being deployed but there is no need to deploy new logic contracts. (you can see this in zos.dev.....json)

1 Like

I assume this may have been a subsequent create when the logic contracts had already been deployed.

As an aside: I noticed that NCDToken doesn’t inherit from Initializable and hence it’s initialize function isn’t explicitly protected by the initializer modifier.
I assume this was your intention.

Also you may want to update the package.json as it still has references to ZepKit repository. https://github.com/itinance/ncd-token/blob/master/package.json

1 Like

@abcoathup thank you so much. I’m curious why the initializer-modifier wasn’t rejected by the Solidity compiler and even not a single warning was thrown without inheriting of Initializable

1 Like

Hi @itinance

Apologies, I missed the initializer modifier is there. (I updated my reply)

The openzeppelin-eth contracts inherit from Initializable and the token contract inherits from these which is why it compiled.

Hi @itinance is this question solved? If so, would you mind marking the reply as the solution, thanks.

1 Like