"Visibility for constructor is ignored" error migrating a simple ERC20 constructor

Getting the following error when trying to migrate the constructor of OpenZeppelin ERC20 Contract

  @openzeppelin/contracts/token/ERC20/ERC20.sol:55:5: Warning: Visibility for constructor is ignored. If you want the contract to be non-deployable, making it "abstract" is sufficient. 
constructor (string memory name_, string memory symbol_) public {
 ^ (Relevant source part starts here and spans across multiple lines).
 ,/C/Users/Asusupernova/Documents/ETH/LastCreator/contracts/MyToken.sol:7:5: Warning: Visibility for constructor is ignored. If you want the contract to be non-deployable, making it "abstract" is sufficient. 
constructor(uint256 initialSupply) public ERC20("Liberation", "LIB") { 
^ (Relevant source part starts here and spans across multiple lines).

:computer: Environment
Truffle v5.1.56 (core: 5.1.56)
Solidity v0.5.16 (solc-js)
Node v12.19.0
Web3.js v1.2.9

Here is my code:

    pragma solidity >=0.4.21 <=0.7.0;

    import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

    contract My is ERC20 {
        constructor(uint256 initialSupply) public ERC20("Liberation", "LIB") {
            _mint(msg.sender, initialSupply);
        }
    }

Here is the OpenZep code: @openzeppelin/contracts/token/ERC20/ERC20.sol:55:5:

    constructor (string memory name_, string memory symbol_) public {
        _name = name_;
        _symbol = symbol_;
        _decimals = 18;
    }
1 Like

Hi @Altaergo,

From: https://docs.soliditylang.org/en/v0.7.5/070-breaking-changes.html#functions-and-events

  • Visibility ( public / external ) is not needed for constructors anymore: To prevent a contract from being created, it can be marked abstract . This makes the visibility concept for constructors obsolete.

I assume that you are actually compiling with Solidity 0.7?

As you are inheriting from OpenZeppelin Contracts, then you may be better to have a pragma solidity that is at least as narrow as what you are inheriting. See: Simple ERC20 token example.

1 Like

I updated the syntax and am encountering another error. This is not even part of my code. Online solutions just seem to be project specific. Btw, is asking questions the only way to trouble shoot or there is another way?

2_deploy_contracts.js
=====================

C:\Users\Asusupernova\AppData\Roaming\npm\node_modules\truffle\build\commands.bundled.js:828606
      .replace(/^\.\//, "")
       ^

TypeError: Cannot read property 'replace' of undefined
    at ResolverIntercept.require (C:\Users\Asusupernova\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\migrate\ResolverIntercept.js:10:1)
1 Like

Hi @Altaergo,

Do you want to share your contract and migrations script? I assume there may be something in your migrations script.

You may want to take a step back and work through the Learn guides: https://docs.openzeppelin.com/learn/

Otherwise look at a tutorial such as: Create an ERC20 using Truffle, without writing Solidity

As for resolving issues like this, it is mostly doing it multiple times so that you can then identify where the issue is likely occurring, e.g. contract, migrations script, test, configuration etc, and then you can just work on that one piece.

When you get stuck, you can start again, and if you still get stuck then you can ask the community. It is worth trying to create a simple example which shows the issue, and often this helps you identify what is the cause.

Yea, am going over those links even as we speak, I’ve been using tutorials which were written in Solidity 0.6, and I only recently learnt that I should try as much as possible to use the most updated version
So far it seems like 50% of the job as a programmer is tinkering with the program till it works

Migrations.sol

    // SPDX-License-Identifier: MIT

    pragma solidity >=0.4.21 <0.8.0;

    contract Migrations {

      address public owner;

      uint public last_completed_migration;

      modifier restricted() {

        if (msg.sender == owner) _;

      }

      constructor()public {

        owner = msg.sender;

      }

      function setCompleted(uint completed) public restricted {

        last_completed_migration = completed;

      }

    }

MyToken.sol

    pragma solidity >=0.4.21 <0.8.0;

    import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

    contract My is ERC20 {

        constructor(uint256 initialSupply) ERC20("Liberation", "LIB") {

            _mint(msg.sender, initialSupply);

        }

    }

1_initial_migration.js

      var Migrations = artifacts.require("./Migrations.sol");

       module.exports = function(deployer) {

         deployer.deploy(Migrations);

       };

2_deploy_contract.js

    var MyToken = artifacts.require(MyToken);

    module.exports = async function (deployer) {

        await deployer.deploy(MyToken, 'Liberation', 'LIB', 100000);

    }
1 Like

Hi @Altaergo,

I tend to use Solidity 0.6 or Solidity 0.7. Solidity 0.8 just got released today.

There were a couple of issues. Your token contract was named My but in the migrations script you were trying to use MyToken. Your constructor only takes one parameter, but in the migrations script you were trying to pass three parameters.

MyToken.sol

pragma solidity >=0.4.21 <0.8.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract MyToken is ERC20 {

    constructor(uint256 initialSupply) ERC20("Liberation", "LIB") {
        _mint(msg.sender, initialSupply);
    }
}

2_deploy_contracts.js

// migrations/2_deploy_contracts.js
const MyToken = artifacts.require("MyToken");

module.exports = async function (deployer) {
  await deployer.deploy(MyToken, '100000000000000000000');
};

Migrate

$ npx truffle develop
Truffle Develop started at http://127.0.0.1:8545/
...
truffle(develop)> migrate

Compiling your contracts...
===========================
> Compiling ./contracts/MyToken.sol
...

Starting migrations...
======================
> Network name:    'develop'
> Network id:      5777
> Block gas limit: 6721975 (0x6691b7)


1_initial_migration.js
======================
...
2_deploy_contracts.js
=====================

   Deploying 'MyToken'
   -------------------
...
truffle(develop)> token = await MyToken.deployed()
undefined
truffle(develop)> (await token.totalSupply()).toString()
'100000000000000000000'
truffle(develop)> await token.name()
'Liberation'
1 Like

Hi @Altaergo,

Solidity has been changing annually, with this, the declaration of constructor has been changed.

For the resolution, we have to:

constructor () {
        candidate = "Candidate 1";
    }

Now, we don’t need to declare the name and visibility of constructor.

2 Likes

Hi @neta,

Welcome to the community :wave:

1 Like

Hi @abcoathup !

Thank you!

1 Like