Name or totalSupply empty after deploying SimpleToken contract

Hello,
I’m trying to build a Token and first things first I’m following some tutorials and examples.

But I’m encountering an issue with the SimpleToken example:

using "@openzeppelin/contracts": "^2.4.0",

pragma solidity ^0.5.0;

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

contract SimpleToken is ERC20, ERC20Detailed {

    /**
     * @dev Constructor that gives _msgSender() all of existing tokens.
     */
    constructor () public ERC20Detailed("SimpleToken", "SIM", 18) {
        _mint(_msgSender(), 10000 * (10 ** uint256(decimals())));
    }
}

I run a local blockchain with ganache-cli --deterministic

Then I deploy the contract using openzeppelin create SimpleToken which gives me back an address that I put in this simple nodejs code:

const Web3 = require('web3');

async function main() {
  // Set up web3 object, connected to the local development network
  const web3 = new Web3('http://localhost:8545');

  const address = '0xC89Ce4735882C9F0f0FE26686c53074E09B0D550';
  const abi = require('./build/contracts/SimpleToken.json').abi;
  const token = new web3.eth.Contract(abi, address);
  const name = await token.methods.name().call();
  console.log(name);
}

main();

But no data is displayed, it’s empty. If I try to use the ganache app to get a GUI, I can’t explore the contract it fails with a JS error. Something about address undefined, I’m not sure the problem is related though.

I’m stuck now.

FYI, the Counter smartcontract worked, I could increase the counter, etc…

I’ll try to add parts of the code little by little to see what’s wrong but it’s a bit tedious and I would like to use this library.

Thank you in advance for your help.

Best regards
Gregory

1 Like

Hi Gregory (@cehraphaim),

Welcome to the community forum :wave:

The reason why this wasn’t working is that OpenZeppelin SDK is for creating upgradeable contracts, and the SimpleToken example you posted is a non-upgradeable contract. Apologies that this is confusing.

https://docs.openzeppelin.com/sdk/2.5/writing-contracts
You can use your Solidity contracts in the OpenZeppelin SDK without any modifications, except for their constructors. Due to a requirement of the proxy-based upgradeability system, no constructors can be used in upgradeable contracts.

To create an upgradeable token using OpenZeppelin SDK then we need to use @openzeppelin/contracts-ethereum-package otherwise we can create a non-upgradeable token and deploy using truffle.

https://docs.openzeppelin.com/sdk/2.5/linking
NOTE: Make sure you install @openzeppelin/contracts-ethereum-package and not the vanilla @openzeppelin/contracts . The latter is set up for general usage, while @openzeppelin/contracts-ethereum-package is tailored for being used with the OpenZeppelin SDK. This means that its contracts are already set up to be upgradeable.

The latest working version of OpenZeppelin Contracts Ethereum Package is 2.2.3 as there was an issue with version 2.3.
openzeppelin link @openzeppelin/contracts-ethereum-package@2.2.3


Example

In an OpenZeppelin SDK project (see Your first project for setup)

Link OpenZeppelin Contracts Ethereum Package and install @openzeppelin/upgrades

openzeppelin link @openzeppelin/contracts-ethereum-package@2.2.3
npm install @openzeppelin/upgrades

SimpleToken.sol

Upgradeable 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())));
    }
}

Create SimpleToken

Get an account to mint the tokens to.

$ oz accounts
? Pick a network development
Accounts for dev-1573097445291:
Default: 0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1
All:
- 0: 0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1

Create the contract, call initialize with the account to hold the tokens.

$ oz create
✓ Compiled contracts with solc 0.5.12 (commit.7709ece9)
? Pick a contract to instantiate SimpleToken
? Pick a network development
All contracts are up to date
? Do you want to call a function on the instance after creating it? Yes
? Select which function * initialize(sender: address)
? sender (address): 0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1
✓ Instance created at 0xCeeFD27e0542aFA926B87d23936c79c276A48277
0xCeeFD27e0542aFA926B87d23936c79c276A48277

Interact

$ oz call
? Pick a network development
? Pick an instance SimpleToken at 0xCeeFD27e0542aFA926B87d23936c79c276A48277
? Select which function name()
✓ Method 'name()' returned: Token
Token

Regards having to use @openzeppelin/contracts-ethereum-package there is a discussion on Planning the demise of OpenZeppelin Contracts’ evil twin, would appreciate any input you had.

Thank you for your complete reply. I actually figured out last night … and I used what you described, the @openzeppelin/contracts-ethereum-package package, and it worked like a charm.

Thank you for pointing out that I should use version 2.2.3.

And thank you in general for all that work. It really helped me get onboard with Ethereum smartcontract

1 Like