0

I am trying to learn how to create ERC20 contract using OpenZeppelin library.

I am trying to create ERC20 contract and set total supply and balance in the code below:

pragma solidity ^0.8.9;

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

contract sampleToken is ERC20 
{
string public name = "ExampleToken";
string public symbol = "EGT";
uint public decimals = 18;
uint public INITIAL_SUPPLY = 10000 * (10 ** decimals);
constructor() public 
    {
_totalSupply = INITIAL_SUPPLY;
_balances[msg.sender] = INITIAL_SUPPLY;
    }
}

in my first try, I have gone to ERC20.sol of openzeppelin library and changed _totalSupply & _balances to internal and I got the below errors

> Compilation warnings encountered:

    Warning: SPDX license identifier not provided in source file. Before publishing, consider adding a comment containing "SPDX-License-Identifier: <SPDX-License>" to each source file. Use "SPDX-License-Identifier: UNLICENSED" for non-open-source code. Please see https://spdx.org for more information.
--> project:/contracts/sampleToken.sol

,Warning: Visibility for constructor is ignored. If you want the contract to be non-deployable, making it "abstract" is sufficient.
  --> project:/contracts/sampleToken.sol:11:1:
   |
11 | constructor() public 
   | ^ (Relevant source part starts here and spans across multiple lines).


TypeError: Overriding public state variable is missing "override" specifier.
 --> project:/contracts/sampleToken.sol:7:1:
  |
7 | string public name = "ExampleToken";
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Note: Overridden public state variable is here:
  --> @openzeppelin/contracts/token/ERC20/ERC20.sol:61:5:
   |
61 |     function name() public view virtual override returns (string memory) {
   |     ^ (Relevant source part starts here and spans across multiple lines).

,TypeError: Public state variables can only override functions with external visibility.
 --> project:/contracts/sampleToken.sol:7:1:
  |
7 | string public name = "ExampleToken";
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Note: Overridden function is here:
  --> @openzeppelin/contracts/token/ERC20/ERC20.sol:61:5:
   |
61 |     function name() public view virtual override returns (string memory) {
   |     ^ (Relevant source part starts here and spans across multiple lines).

,TypeError: Overriding public state variable is missing "override" specifier.
 --> project:/contracts/sampleToken.sol:8:1:
  |
8 | string public symbol = "EGT";
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Note: Overridden public state variable is here:
  --> @openzeppelin/contracts/token/ERC20/ERC20.sol:69:5:
   |
69 |     function symbol() public view virtual override returns (string memory) {
   |     ^ (Relevant source part starts here and spans across multiple lines).

,TypeError: Public state variables can only override functions with external visibility.
 --> project:/contracts/sampleToken.sol:8:1:
  |
8 | string public symbol = "EGT";
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Note: Overridden function is here:
  --> @openzeppelin/contracts/token/ERC20/ERC20.sol:69:5:
   |
69 |     function symbol() public view virtual override returns (string memory) {
   |     ^ (Relevant source part starts here and spans across multiple lines).

,TypeError: Overriding public state variable is missing "override" specifier.
 --> project:/contracts/sampleToken.sol:9:1:
  |
9 | uint public decimals = 18;
  | ^^^^^^^^^^^^^^^^^^^^^^^^^
Note: Overridden public state variable is here:
  --> @openzeppelin/contracts/token/ERC20/ERC20.sol:86:5:
   |
86 |     function decimals() public view virtual override returns (uint8) {
   |     ^ (Relevant source part starts here and spans across multiple lines).

,TypeError: Public state variables can only override functions with external visibility.
 --> project:/contracts/sampleToken.sol:9:1:
  |
9 | uint public decimals = 18;
  | ^^^^^^^^^^^^^^^^^^^^^^^^^
Note: Overridden function is here:
  --> @openzeppelin/contracts/token/ERC20/ERC20.sol:86:5:
   |
86 |     function decimals() public view virtual override returns (uint8) {
   |     ^ (Relevant source part starts here and spans across multiple lines).

,TypeError: Overriding public state variable return types differ.
 --> project:/contracts/sampleToken.sol:9:1:
  |
9 | uint public decimals = 18;
  | ^^^^^^^^^^^^^^^^^^^^^^^^^
Note: Overridden public state variable is here:
  --> @openzeppelin/contracts/token/ERC20/ERC20.sol:86:5:
   |
86 |     function decimals() public view virtual override returns (uint8) {
   |     ^ (Relevant source part starts here and spans across multiple lines).

,TypeError: Contract "sampleToken" should be marked as abstract.
 --> project:/contracts/sampleToken.sol:5:1:
  |
5 | contract sampleToken is ERC20 
  | ^ (Relevant source part starts here and spans across multiple lines).
Note: Missing implementation: 
  --> @openzeppelin/contracts/token/ERC20/ERC20.sol:53:5:
   |
53 |     constructor(string memory name_, string memory symbol_) {
   |     ^ (Relevant

Then after my research, I have return all the state of the variables back to private and used _mint function instead as can be seen below

pragma solidity ^0.8.9;

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

contract sampleToken is ERC20 
{
string public name = "ExampleToken";
string public symbol = "EGT";
uint public decimals = 18;
uint public INITIAL_SUPPLY = 10000 * (10 ** decimals);
constructor() public 
    _mint(msg.sender, INITIAL_SUPPLY);
}

and I get the below error

> Compilation warnings encountered:

    Warning: SPDX license identifier not provided in source file. Before publishing, consider adding a comment containing "SPDX-License-Identifier: <SPDX-License>" to each source file. Use "SPDX-License-Identifier: UNLICENSED" for non-open-source code. Please see https://spdx.org for more information.
--> project:/contracts/sampleToken.sol

,Warning: Visibility for constructor is ignored. If you want the contract to be non-deployable, making it "abstract" is sufficient.
  --> project:/contracts/sampleToken.sol:11:1:
   |
11 | constructor() public 
   | ^ (Relevant source part starts here and spans across multiple lines).


SyntaxError: Functions without implementation cannot have modifiers.
  --> project:/contracts/sampleToken.sol:11:1:
   |
11 | constructor() public 
   | ^ (Relevant source part starts here and spans across multiple lines).

,TypeError: Overriding public state variable is missing "override" specifier.
 --> project:/contracts/sampleToken.sol:7:1:
  |
7 | string public name = "ExampleToken";
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Note: Overridden public state variable is here:
  --> @openzeppelin/contracts/token/ERC20/ERC20.sol:61:5:
   |
61 |     function name() public view virtual override returns (string memory) {
   |     ^ (Relevant source part starts here and spans across multiple lines).

,TypeError: Public state variables can only override functions with external visibility.
 --> project:/contracts/sampleToken.sol:7:1:
  |
7 | string public name = "ExampleToken";
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Note: Overridden function is here:
  --> @openzeppelin/contracts/token/ERC20/ERC20.sol:61:5:
   |
61 |     function name() public view virtual override returns (string memory) {
   |     ^ (Relevant source part starts here and spans across multiple lines).

,TypeError: Overriding public state variable is missing "override" specifier.
 --> project:/contracts/sampleToken.sol:8:1:
  |
8 | string public symbol = "EGT";
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Note: Overridden public state variable is here:
  --> @openzeppelin/contracts/token/ERC20/ERC20.sol:69:5:
   |
69 |     function symbol() public view virtual override returns (string memory) {
   |     ^ (Relevant source part starts here and spans across multiple lines).

,TypeError: Public state variables can only override functions with external visibility.
 --> project:/contracts/sampleToken.sol:8:1:
  |
8 | string public symbol = "EGT";
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Note: Overridden function is here:
  --> @openzeppelin/contracts/token/ERC20/ERC20.sol:69:5:
   |
69 |     function symbol() public view virtual override returns (string memory) {
   |     ^ (Relevant source part starts here and spans across multiple lines).

,TypeError: Overriding public state variable is missing "override" specifier.
 --> project:/contracts/sampleToken.sol:9:1:
  |
9 | uint public decimals = 18;
  | ^^^^^^^^^^^^^^^^^^^^^^^^^
Note: Overridden public state variable is here:
  --> @openzeppelin/contracts/token/ERC20/ERC20.sol:86:5:
   |
86 |     function decimals() public view virtual override returns (uint8) {
   |     ^ (Relevant source part starts here and spans across multiple lines).

,TypeError: Public state variables can only override functions with external visibility.
 --> project:/contracts/sampleToken.sol:9:1:
  |
9 | uint public decimals = 18;
  | ^^^^^^^^^^^^^^^^^^^^^^^^^
Note: Overridden function is here:
  --> @openzeppelin/contracts/token/ERC20/ERC20.sol:86:5:
   |
86 |     function decimals() public view virtual override returns (uint8) {
   |     ^ (Relevant source part starts here and spans across multiple lines).

,TypeError: Overriding public state variable return types differ.
 --> project:/contracts/sampleToken.sol:9:1:
  |
9 | uint public decimals = 18;
  | ^^^^^^^^^^^^^^^^^^^^^^^^^
Note: Overridden public state variable is here:
  --> @openzeppelin/contracts/token/ERC20/ERC20.sol:86:5:
   |
86 |     function decimals() public view virtual override returns (uint8) {
   |     ^ (Relevant source part starts here and spans across multiple lines).

,TypeError: Contract "sampleToken" should be marked as abstract.
 --> project:/contracts/sampleToken.sol:5:1:
  |
5 | contract sampleToken is ERC20 
  | ^ (Relevant source part starts here and spans across multiple lines).
Note: Missing implementation: 
  --> @openzeppelin/contracts/token/ERC20/ERC20.sol:53:5:
   |
53 |     constructor(string memory name_, string memory symbol_) {
   |     ^ (Relevant source part starts here and spans across multiple lines).

,TypeError: Referenced declaration is neither modifier nor base class.
  --> project:/contracts/sampleToken.sol:12:5:
   |
12 |     _mint(msg.sender, INITIAL_SUPPLY);
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

,TypeError: Constructor must be implemented if declared.
  --> project:/contracts/sampleToken.sol:11:1:
   |
11 | constructor() public 
   | ^ (Relevant source part starts here and spans across multiple lines).

please guide me on how to fix these issues.

1 Answer 1

0

Your biggest issue comes from not calling the ERC-20 constructor. Notice ERC20(name, symbol) on the constructor line.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;

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

contract myERC20Token is ERC20 
{
    constructor(string memory name, string memory symbol, uint256 initialSupply) ERC20(name, symbol) {
        _mint(msg.sender, initialSupply);
    }
    
    function decimals() public view virtual override returns (uint8) {
        return 10;
    }
}

Then, the decimals is not a variable in the Open zeppelin implementations, it is a function that you can override if you need to, just like I did in the previous code example :

If you are fine with the default 18 decimals :

function decimals() public view virtual override returns (uint8) {
    return 18;
}

then there is no need to override the decimals function.

By the way the ERC-20 implementation already internally defines :

uint256 private _totalSupply;
string private _name;
string private _symbol;

So there is really no need for you to hold similar variables in your child contract.

2
  • How would one specify the name and symbol of a new token, statically? By overwritting _name and _symbol? Or by calling the parent constructor with the immediate values? And how?
    – Incerteza
    Dec 30, 2021 at 21:28
  • @Incerteza just replace the name and symbol in ERC20(name, symbol) by string literals such as "Ethereum" and "ETH" for example. constructor() ERC20("Ethereum", "ETH") { ... }
    – hroussille
    Apr 25, 2022 at 21:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.