Compiling ERC20: Warning: The "extcodehash" instruction is not supported by the VM version "byzantium"

Hi, I am having trouble trying to compile a simple ERC20 token contract and the Crowdsale.sol doc. I had compiled my simple ERC20 token with the most current version of OpenZeppelin, however, I had to switch to OZ 2.5 to incorporate the Crowdsale.sol. Now I am getting the following errors:

I had to install @openzeppelin 2.5 locally instead of the latest version 3.x in order to run the crowdsale.sol contract. I also changed my pragmas on my two contracts to ^0.5.0 and truffle-config
However, i am getting a number of errors now which I didn’t have before:

 @openzeppelin/contracts/utils/Address.sol:31:32: Warning: The "extcodehash" instruction is not supported by the VM version "byzantium" you are currently compiling for. It will be interpreted as an invalid instruction on this VM.
        assembly { codehash := extcodehash(account) }
                               ^------------------^

CompileError: /Users/me/Desktop/final-7/contracts/MyToken.sol:18:61: TypeError: Wrong argument count for modifier invocation: 2 arguments given but expected 0.
    constructor(string memory _name, string memory _symbol) ERC20(_name, _symbol) public
1 Like

Hey, I think you should increase the compile version to 0.5.5, cause petersburg was added in 0.5.5

2 Likes

@skyge but all of the OZ contracts are 5.0. Should I go and change them all to 5.5?

1 Like

I think they use pragma solidity ^0.5.0;, so you can change your compile version in the config file.

2 Likes

@Skyge but don’'t the pragma in OZ smart contracts and truffle-config compiler version have to match? So do I use 5.0 or 5.5 for all?

1 Like

In contract, use pragma solidity ^0.5.0;, so in your config, you can use 0.5.5, they are compatible.

2 Likes

Hi @crypto_economics,

Have a look at Simple ERC20 Crowdsale.

You need to compile with Solidity 0.5.5 or a later 0.5 version.

1 Like

@Skyge @abcoathup hi thank you for your help! That worked however, I was having some trouble compiling the contracts as my simpletoken ccontract is setup a bit different:

pragma solidity ^0.5.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/ownership/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20Pausable.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";

contract MyToken is ERC20, Pausable, Ownable {
   constructor(string memory _name, string memory _symbol) ERC20(_name, _symbol) public { 
        _mint(msg.sender, 1000);
    }

I managed to get the contracts to compile by making some adjustments to may contract to incorporate some of the items from Simple ERC20 Crowdsale. Most importantly, I included Context.sol, and ERC20Detailed under My Contract is...which seemed to work. However, I am not sure if these changes to my contracts are going to affect previous tests that I wrote on my original contract as I willl have to run them again on this new contract.

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/ownership/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20Pausable.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20Detailed.sol";

     constructor(
        string memory name,
        string memory symbol,
        uint256 initialSupply
        //uint256 initialSupply
    ) public ERC20Detailed(name, symbol, 18) {
        _mint(_msgSender(), 1000);
    }
}
1 Like

Hi @crypto_economics,

Your ERC20 above is using a constructor which names a name and symbol, this is in OpenZeppelin Contracts 3.x. In OpenZeppelin Contracts 2.x we use ERC20Detailed.
See: Simple ERC20 Crowdsale.

1 Like

Hi @abcoathup thank your explanation. I will try and run my tests again however they worked on my original contract based on OpenZepp 3.x and ERC20.sol. Do you anticipate any problems?

const BigNumber =web3.BigNumber;
const BN = require('bn.js');
const { should, use } = require('chai');
const MyToken = artifacts.require('MyToken');

require('chai')
use(require('chai-bignumber')(BigNumber))
.should();

contract('MyToken', accounts => {
    const _name = 'MyToken';
    const _symbol = 'MTK';
    const _decimals = '18';
       
beforeEach(async function() {
    this.token = await MyToken.new(_name, _symbol);
    });

describe('token.initialized', function() {
    it ('has correct name', async function(){
        const name = await this.token.name();
        name.should.equal(_name);
    })
    it ('has correct symbol', async function(){
        const symbol = await this.token.symbol();
        symbol.should.equal(_symbol);
    })
    it ('has correct decimals', async function(){
        const decimals = (await this.token.decimals()).toNumber();
        decimals.should.be.bignumber.equal(_decimals);
    })
    it('Initial supply allocated to Admin account', async () => {
        const tokenInstance = await MyToken.deployed()
            , initSupply    = 1000
            , adminBalance  = await tokenInstance.balanceOf(accounts[0])
        assert.equal(adminBalance.toNumber(), initSupply, 'Initial supply should be allocated to admin account!')
      })
    it('sets the total supply as initialSupply', async () => {
        const tokenInstance = await MyToken.deployed()
            , initSupply    = 1000
            , totalSupply   = await tokenInstance.totalSupply()
        assert.equal(totalSupply.toNumber(), initSupply, `Total supply should be ${initSupply}!`)
      })
    })
  });
1 Like

Hi @crypto_economics,

I don’t see a reason for your tests not to pass. You are using standard ERC20 functionality. The only thing that may change is any constructor parameters when you create your token.

1 Like

@abcoathup hi, in my contract which incorporates the Simple token example you provided, is the initial supply set to 1000 and do i have to include this in the 2_deploy_contracts.js file under migrations?

1 Like

Hi @crypto_economics,

You are not using the parameter uint256 initialSupply so it can be removed, in your migrations script you only need to supply name and symbol.

Please note the default decimals is 18. So a total supply of 1000 is much less than 1 token of 1,000,000,000,000,000,000. See: https://docs.openzeppelin.com/contracts/3.x/erc20#a-note-on-decimals

1 Like

@abcoathup thank you. I took your guidance on this and changed my contract to this:

   constructor(
        string memory name,
        string memory symbol,
        uint256 initialSupply
    ) public ERC20Detailed(name, symbol, 18) {
        _mint(_msgSender(), initialSupply);
    }
}

I managed to deploy the contracts succesfully. Thank you for all of your help!

1 Like

@abcoathup hi. I ran my tests again, had to make a few changes, but I got them to all pass! Thanks again for your help. Honestly, OpenZeppelin is unbelievably helpful.

1 Like

Hi @crypto_economics,

Glad you have passing unit tests. I suggest adding code coverage and target 100% code coverage.

1 Like

A post was split to a new topic: What is code coverage?

A post was merged into an existing topic: What is code coverage?