Deploying a token that uses 'contracts-ethereum-package' to Ethereum Classic

I have successfully deployed my token (standard token that inherits from ERC20Detailed) to the Ropsten network using an Infura provider but I cannot deploy the token to Ethereum Classic. The Kotti testnet does not have a copy of the contracts-ethereum-package contracts deployed and when I try to deploy them myself - I run into multiple issues.

:computer: Environment
MacOS Mojave
Truffle v5.0.37
OpenZeppelin 2.5.3

:memo:Details
I am currently deploying to ETC’s Kotti testnet.
I have an ETC testnet account funded with testnet ETC.
I get the following output:

$ openzeppelin push                                                
Nothing to compile, all contracts are up to date.
? Pick a network kotti
? One or more linked dependencies are not yet deployed on dev-6.
Do you want to deploy them now? Yes
✖ Deploying @openzeppelin/contracts-ethereum-package dependency to network dev-6
Failed deployment of dependency @openzeppelin/contracts-ethereum-package with error: Failed to check for transaction receipt:
{}

:1234: Code to reproduce
My networks.js file looks like this:

require('dotenv').config();
const HDWalletProvider = require('truffle-hdwallet-provider');
module.exports = {
  compilers: {
    solc: {
      version: '0.5.1',
      settings: {
        evmVersion: 'byzantium'
      }
    }
  },
  networks: {
    kotti: {
      provider: () => new HDWalletProvider(
        [process.env.DEV_PRIVATE_KEY], 
        "https://www.ethercluster.com/kotti"),
      networkId: '6'
    }
  }
};

My token looks like this:

pragma solidity ^0.5.0;

// Import base Initializable contract
import "@openzeppelin/upgrades/contracts/Initializable.sol";

// Import interface and library from OpenZeppelin contracts
import "@openzeppelin/contracts-ethereum-package/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts-ethereum-package/contracts/token/ERC20/ERC20Detailed.sol";
import "@openzeppelin/contracts-ethereum-package/contracts/token/ERC20/ERC20Mintable.sol";
import "@openzeppelin/contracts-ethereum-package/contracts/math/SafeMath.sol";

contract SlccToken is ERC20, ERC20Detailed, ERC20Mintable {
  using SafeMath for uint256;

  function initialize() public initializer {
    ERC20Detailed.initialize("OZ Test token", "OZTEST", 2);
    ERC20Mintable.initialize(msg.sender);
    mint(msg.sender, 1000000000000 * (10 ** uint256(2)));
  }

}

ETC is currently at feature-parity with Byzantium and unless that EVM version is targeted some common tools have been known to fail hence why I was asked to put the compilers object in there by someone in the ETC discord but looking at your documentation, I don’t think it gets picked up.

1 Like

Hi @husainfazel,

I was able to deploy standard contracts to Kotti using Truffle.

In the OpenZeppelin CLI we can set the compiler version and the EVM version for the upgradeable contract.

I wasn’t able to deploy upgradeable contracts to Kotti using the OpenZeppelin CLI.
I assume the issue is the EVM version of the compiled Proxy and ProxyAdmin contracts being deployed.

I can see that Agharta is coming to Kotti in December so assume it should work then.

Will see if there are any other options in the meantime.

Thanks for the reply, I will see if I can deploy to one of the existing Agharta testnets and see if that fixes the problem.

Can I ask where the setting for compiler/EVM version is in OpenZeppelin CLI?

1 Like

Hi @husainfazel,

A Byzantium version of OpenZeppelin CLI has been created so you should now be able to deploy the token. This has the contracts (e.g. Proxy and ProxyAdmin) compiled for Byzantium.

First install the Byzantium version (I did this locally in the project):

npm i @openzeppelin/cli@byzantium

Compile the contracts specifying the solc version and EVM version.

npx oz compile --solc-version 0.5.3 --evm-version byzantium

Finally create the contract

npx oz create

Below is the output I got when creating the contract on Kotti.

$ npx oz compile --solc-version 0.5.3 --evm-version byzantium
✓ Compiled contracts with solc 0.5.3 (commit.10d17f24)

$ npx oz create
Nothing to compile, all contracts are up to date.
? Pick a contract to instantiate Token
? Pick a network kotti
✓ Added contract Token
? One or more linked dependencies are not yet deployed on dev-6.
Do you want to deploy them now? Yes
✓ Deploying @openzeppelin/contracts-ethereum-package dependency to network dev-6
✓ Contract Token deployed
All contracts have been deployed
? Call a function to initialize the instance after creating it? Yes
? Select which function * initialize()
✓ Instance created at 0x0bF01A567f4f749F1d71493B0653220DEB121815
0x0bF01A567f4f749F1d71493B0653220DEB121815 

I suggest that the Issue on GitHub can be closed: https://github.com/OpenZeppelin/openzeppelin-contracts-ethereum-package/issues/72

I’ve tested that the Byzantium version of the CLI works and closed the Github issue

Thanks for the speed response and solution!

1 Like

Hi @husainfazel,

Glad that you are up and running.

Would be great if you could share what you are building on Ethereum Classic.
Either in What are you working on? or in the #general:showcase category.


As an aside, in the sample token code you provided, you import SafeMath but don’t use it (I assume you provided cut down code). Also in the initialize function you could call _mint rather than mint and use decimals() rather than hardcoding the decimal value.

An example upgradeable SimpleToken (not mintable) is as follows:

SimpleToken

pragma solidity ^0.5.0;

import "@openzeppelin/upgrades/contracts/Initializable.sol";

import "@openzeppelin/contracts-ethereum-package/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts-ethereum-package/contracts/token/ERC20/ERC20Detailed.sol";

/**
 * @title SimpleToken
 * @dev Very simple ERC20 Token example, where all tokens are pre-assigned to the sender.
 * Note they can later distribute these tokens as they wish using `transfer` and other
 * `ERC20` functions.
 */
contract SimpleToken is Initializable, ERC20, ERC20Detailed {

    /**
     * @dev initialize that gives msg.sender all of existing tokens.
     */
    function initialize(address sender) public initializer {
        ERC20Detailed.initialize("Token", "TKN", 18);
        _mint(sender, 1000000 * (10 ** uint256(decimals())));
    }
}