How to call mint after a contract is deployed?

Hi, I only have question that I’m not clear enough.

So, currently I have a Token and a Crowdsale.

I give my Token (which inherit ERC20Detailed, ERC20Mintable) an initial supply.
Then transfer it to my Crowdsale to make public able to purchase the token from my contract.

Since I already implemented ERC20Mintable to my token.
I should be able to use mint function to add my total supply anytime.
I did able to do this using truffle, after getting the token instance (Token.deployed()).
For example, something like this => token.mint(target_addr, amount)

My questions are:

  1. How to call the method after it is deployed (either in testnet or mainnet) without using truffle ?
    In my case, I used web3.js. I can access mint function from the Token Contract instance:
    For example: instance.methods.mint(target_addr, amount)
    It is return TRUE value, but it is not adding any total supply value. (truffle does)
    Is there any example, how to call mint function after the contract is deployed?

  2. Let’s say I manage to run the mint function.
    I wonder, does not this mean mint can be called by anyone ?
    They just need to get the ABI and contract address, then can use the mint function.
    While those information can be fetched from Etherscan.
    How mint know, if the caller is the onlyMinter, after it is deployed ?
    Because mint function did not ask parameter for something like private key, or any credentials,
    to show that the caller is the onlyMinter.

Please, help me to understand this.

1 Like

Hi @Charles808 welcome to the community :wave:

How to mint tokens

You can call mint from any address that has the MinterRole. See the ERC20Mintable mint API
You can interact with your contract in multiple ways, e.g. from truffle, or a dapp using MetaMask. The account must have the MinterRole, e.g. truffle or MetaMask must be configured with this account.

You can use truffle console with the specified network

$ npx truffle console --network development
> myToken = await MyToken.deployed()
> myToken.mint("0xFFcf8FDEE72ac11b5c542428B35EEF5769C409f0", "100000000000000000000")
> (await myToken.balanceOf("0xFFcf8FDEE72ac11b5c542428B35EEF5769C409f0")).toString()

You can use truffle exec with the specified network to execute a script.

$ npx truffle exec mint.js --network development
// mint.js
const MyToken = artifacts.require("MyToken");

module.exports = async function(callback) {

    const myToken = await MyToken.deployed();
    await myToken.mint("0xFFcf8FDEE72ac11b5c542428B35EEF5769C409f0", "100000000000000000000");
    console.log("Minting complete");

    callback();
}

You can interact with your contract on Etherscan using MetaMask once the code is verified. To verify you can follow the guide: Verifying a contract inheriting from OpenZeppelin Contracts


You can interact with your contract using a dapp and MetaMask.
Tools like OneClickDapp (https://oneclickdapp.com) will generate a dapp using the ABI and the contract address.

How only addresses with the MinterRole can mint

You can only call mint from an address that has the MinterRole.

The mint function in ERC20Mintable uses the modifier onlyMinter

contract ERC20Mintable is ERC20, MinterRole {
    /**
     * @dev See {ERC20-_mint}.
     *
     * Requirements:
     *
     * - the caller must have the {MinterRole}.
     */
    function mint(address account, uint256 amount) public onlyMinter returns (bool) {
        _mint(account, amount);
        return true;
    }
}

The onlyMinter modifier in MinterRole requires that the caller is a Minter, otherwise it reverts with the message “MinterRole: caller does not have the Minter role”

    modifier onlyMinter() {
        require(isMinter(msg.sender), "MinterRole: caller does not have the Minter role");
        _;
    }

    function isMinter(address account) public view returns (bool) {
        return _minters.has(account);
    }

You can look at the ERC20Mintable.behavior.js tests to see how this is tested.

You can also read more on Role Based Access Control in the documentation.


Please let me know if you need any more information.


As an aside, you describe minting tokens and transferring them to a Crowdsale for sale. You may want to consider using a minted crowdsale for the token emission of your crowdsale.

See token emission of the Crowdsale documentation.

Also see the SampleCrowdsale.sol


I moved this topic to the #support:contracts category.

Hi @abcoathup

Excellent and neat response !
I greatly appreciated your effort for giving me such a complete answers.

About your suggestion:
“As an aside, you describe minting tokens and transferring them to a Crowdsale for sale. You may want to consider using a minted crowdsale for the token emission of your crowdsale.”

Correct me if I’m wrong.
But I think, Minted Crowdsale emission minted the token when there is a purchase.
While, what I need is a CrowdSale with limited amount of Token Supply.
But, I can mint it anytime, in case I need to add the Total Supply.

Therefore, I did not use the Minted Crowdsale emission, but the default emission.
Because I need to limit the Total Supply, but can be added anytime.
Therefore, I used Default Emission + ERC20Mintable.

I’m open to any suggestion though.
But as far as I already learned, Minted Crowdsale emission is not suitable for my scenario.

Thank you very much !

1 Like

Hi @Charles808

Glad to be of help. Please ask all the questions that you need.

Either option works:

  • Default emission - Mint a supply of tokens and transfer them to the Crowdsale
  • MintedCrowdsale - Give the MintedCrowdsale the MinterRole and mint as tokens are purchased.

With either option you can still have keep a MinterRole which allows additional minting, though I suggest that you clearly advise your users under what circumstances further tokens could be minted.

Using ERC20Capped could be a possibility depending on your tokenomics.