How to pass arguments to "zos create --init" properly?

Hi. My contract has the following initialize-method:

function initialize(
    address minter,
    address[] memory pausers
) public initializer {
}

How can I pass the second arguments on zos create properly? And how can I achieve, that inherited initialize-methods also were called properly within this method (second part of the question below).

I have tried the following:

zos create NCDToken --init initialize --args 0x6c32ee3d8dcd2a88142c6ba35fc97ce92904f086, [0x6c32ee3d8dcd2a88142c6ba35fc97ce92904f086, 0xbc19d2a8f611d7f81757420a1cd6a41148a3c9e4]

Ends up with:

Using custom deployment of openzeppelin-eth
All logic contracts are up to date
Error parsing arguments: SyntaxError: Unexpected token ] in JSON at position 46

zos create NCDToken --init initialize --args '0x6c32ee3d8dcd2a88142c6ba35fc97ce92904f086', ['0x6c32ee3d8dcd2a88142c6ba35fc97ce92904f086', '0xbc19d2a8f611d7f81757420a1cd6a41148a3c9e4']

Ends up with the same error message.

Then I tried a "flattened" array with only one parameter:

zos create NCDToken --init initialize --args 0x6c32ee3d8dcd2a88142c6ba35fc97ce92904f086, 0x6c32ee3d8dcd2a88142c6ba35fc97ce92904f086

Same error message.

Then I have eliminated the spaces between arguments:

zos create NCDToken --init initialize --args 0x6c32ee3d8dcd2a88142c6ba35fc97ce92904f086,[0x6c32ee3d8dcd2a88142c6ba35fc97ce92904f086,0xbc19d2a8f611d7f81757420a1cd6a41148a3c9e4]

It seems to work better. But first I was curious why it still was asking for "decimals", as the initialize-method of ERC20Detailed is already called within the main initialize-method.

Second, it could not parse either the other arguments seemingly:

sing session with network development, sender address 0xe280db001246e1cff4b437d161f47e4a8895506d, timeout 3600 seconds
WARNING: Address 0xe280db001246e1cff4b437d161f47e4a8895506d is not checksummed. Consider checksumming it to avoid future warnings or errors.
Using session with network development, sender address 0xe280db001246e1cff4b437d161f47e4a8895506d, timeout 3600 seconds
WARNING: Address 0xe280db001246e1cff4b437d161f47e4a8895506d is not checksummed. Consider checksumming it to avoid future warnings or errors.
Using custom deployment of openzeppelin-eth
All logic contracts are up to date
? decimals: 18
Deploying new ProxyAdmin...
Deployed ProxyAdmin at 0xfc0756F0642D877662EBEEd9c5D5A9e8A3c88fC1
invalid string value (arg="", coderType="string", value=["0x6c32ee3d8dcd2a88142c6ba35fc97ce92904f086","0xbc19d2a8f611d7f81757420a1cd6a41148a3c9e4"], version=4.0.30)
Updated zos.dev-1561494218904.json

For the sake of completeness, the whole token contract looks like this and can be found on GitHub:

    pragma solidity ^0.5.7;

    import "openzeppelin-eth/contracts/token/ERC20/ERC20Detailed.sol";
    import "openzeppelin-eth/contracts/token/ERC20/ERC20Mintable.sol";
    import "openzeppelin-eth/contracts/token/ERC20/ERC20Pausable.sol";
    import "openzeppelin-eth/contracts/ownership/Ownable.sol";

    contract NCDToken is ERC20Detailed, ERC20Mintable, ERC20Pausable {

        function initialize(
            address minter,
            address[] memory pausers
        ) public initializer {

            require(pausers[0] != address(0));

            ERC20Detailed.initialize("NCDToken", "NCD", uint8(18));
            ERC20Mintable.initialize(minter);

            ERC20Pausable.initialize(pausers[0]);

            // add the other pausers as well if existing
            for (uint256 i = 1; i < pausers.length; ++i) {
                _addPauser(pausers[i]);
            }
        }

        function () external payable {
            //revert();
        }

        /**
         * @dev Minting tokens
         * @param account The account of beneficiary who will get the minted token
         * @param value The amount of minted token
         */
        function _mint(address account, uint256 value) internal whenNotPaused onlyMinter {
            super._mint(account, value);
        }

    }
1 Like

Hi @itinance

I suggest you look to upgrade to ZeppelinOS 2.4, the new interactive commands are awesome.

Using ZeppelinOS 2.4 I was able to quickly and easily deploy and initialize the token contract.

The new interactive commands walk you through the initialization, and you get to choose the appropriate initialize function.

$ npx zos create
✓ Compiled contracts with solc 0.5.10 (commit.5a6ea5b1)
? Pick a contract to instantiate Token
? Pick a network development
✓ Added contract Token
✓ Contract Token deployed
All contracts have been deployed
? Do you want to call a function on the instance after creating it? Yes
? Select which function * initialize(minter: address, pausers: address[])
? minter (address): 0x90f8bf6a479f320ead074411a4b0e7944ea8c9c1
? pausers (address[]): [0x90f8bf6a479f320ead074411a4b0e7944ea8c9c1,0xffcf8fdee72ac11b5c542428b35eef5769c409f0]
✓ Setting everything up to create contract instances
✓ Instance created at 0x26b4AFb60d6C903165150C6F0AA14F8016bE4aec
0x26b4AFb60d6C903165150C6F0AA14F8016bE4aec

Once the instance is deployed and initialized, you can manually test it, e.g. by checking that the second address provided in the pauser array isPauser

$ npx zos call
? Pick a network development
? Pick an instance Token at 0x26b4AFb60d6C903165150C6F0AA14F8016bE4aec
? Select which function isPauser(account: address)
? account (address): 0xffcf8fdee72ac11b5c542428b35eef5769c409f0
✓ Method 'isPauser(address)' returned: true
true

Regards the decimals error, there are three initializer functions. When you were attempting to initialize, the second initialize taking two strings and a uint8 decimals parameter was shown in your error.

To initialize via the command line you need to specify the fully qualified function name.

  * initialize(sender: address)
  * initialize(name: string, symbol: string, decimals: uint8)
  * initialize(minter: address, pausers: address[])

In this case it is "initialize(minter: address, pausers: address[])"

npx zos create SimpleToken --network development --init "initialize(minter: address, pausers: address[])" --args 0x90f8bf6a479f320ead074411a4b0e7944ea8c9c1,[0x90f8bf6a479f320ead074411a4b0e7944ea8c9c1,0xffcf8fdee72ac11b5c542428b35eef5769c409f0]

As an aside, ganache-cli doesn't display addresses with checksums, I created an issue for this https://github.com/trufflesuite/ganache-cli/issues/657 and someone has done a Pull Request already.

Wow! That works really great! 2.4 is brilliant and fixes my issues automatically

By the way, what is the owner then? I guess its the first account in ganache, isn’t it?

Propbaly can define it with zos create --from $owner?

1 Like

I have tried all ganache-accounts, nobody is suitable to send-tx where isOwner-modifier is required. Which account would be the owner if not specified in zos create?

1 Like

Happy to hear that!

You'll have to manually call Ownable.initialize(theAccountYouWantToBeTheOwner) in your own initializer. Unfortunately, initializers are not called automatically (like constructors), so you need to handle the call to the initializers of your base contracts manually.

2 Likes

@itinance
I just noticed that currently the NCDToken doesn’t inherit from Ownable it only imports it.

A minor point:
Roles.sol includes a check when adding for the 0 address.

1 Like

I updated my answer to include how to initialize via the command line and marked the reply as the solution:

1 Like