DEV Community

Zubair Khalid
Zubair Khalid

Posted on • Updated on

OpenZeppelin ERC777 Token Quick Tutorial on Local Testnet (Ganache/Geth)

Hola Amigos! In this tutorial, I want to demonstrate how you can implement and use OpenZeppelin ERC777 Token on a local testnet e.g., Ganache. I am not going into the details of ERC777 and how it is different from ERC20. I hope you already know those details, if not I highly suggest you first understand that. The original documentation lacks even a simple tutorial on how to use this token standard from OpenZeppeline contracts. OpenZeppelin ERC777 needs ERC1820 registry contract to work. This registry contract is installed by default on all public testnets and mainnet but on the local testnet like Ganache or Geth-dev you have to do some extra steps to get it working. If you try to deploy ERC777 without doing these steps and get something like the following error, this tutorial is definitely for you.

"MyToken" hit a require or revert statement somewhere in its constructor. Try:
   * Verifying that your constructor params satisfy all require conditions.
   * Adding reason strings to your require statements.
Enter fullscreen mode Exit fullscreen mode

Prerequisites:
Please install these tools if you have not already did.

  • NodeJs (LTS Recommended)
  • Truffle
  • Ganache (or Geth)

Steps:

Step 1. Create a new directory and name it anything, like 'ERC777'.

mkdir ERC777
cd ERC777
Enter fullscreen mode Exit fullscreen mode

Step 2. Initialize NPM and truffle inside the directory.

npm init
truffle init
Enter fullscreen mode Exit fullscreen mode

Step 3. Edit truffle-config.js to configure truffle to work with Ganache (or Geth).

networks: {
 development: {
     host: "127.0.0.1",     // Localhost (default: none)
     port: 8545,            // Standard Ethereum port (default: none)
     network_id: "*",       // Any network (default: none)
     gas: 6721975
    }
}
Enter fullscreen mode Exit fullscreen mode

Step 4. Install following packages using NPM.

npm install @openzeppelin/contracts
npm install --save-dev @openzeppelin/test-helpers
Enter fullscreen mode Exit fullscreen mode

Step 5. Create an example ERC777 contract, and extend it from OpenZeppline ERC777.

// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.9.0;

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

contract MyToken is ERC777{

    constructor (uint _initSupply, address[] memory defaultOperators) ERC777("MYToken", "MYT", defaultOperators) {
    {
        _mint(msg.sender, _initSupply * (10 ** decimals()), "", "");
    }
}
}
Enter fullscreen mode Exit fullscreen mode

Step 6. Now head over to the Migrations director and create a new migration file, name it something like 2_deploy_contracts.js.

Step 7. Add following piece of code in that file. You can modify the code as per your need.

const myToken = artifacts.require('MyToken');

require('@openzeppelin/test-helpers/configure')({ provider: web3.currentProvider, environment: 'truffle' });

const { singletons } = require('@openzeppelin/test-helpers');

module.exports = async function (deployer, network, accounts) {
  if (network === 'development') {
    // In a test environment an ERC777 token requires deploying an ERC1820 registry
    await singletons.ERC1820Registry(accounts[0]);
  }

  await deployer.deploy(myToken, 1000000, []);
};
Enter fullscreen mode Exit fullscreen mode

This code deploys both ERC1820 registry and your token contract with the help of '@openzeppelin/test-helpers package.

Step 8. You need to write some unit tests to test your token contract. Let's create a test file named MyToken.test.js inside the test directory and write our unit tests.

require('@openzeppelin/test-helpers/configure')({ provider: web3.currentProvider, environment: 'truffle' });

const {singletons } = require('@openzeppelin/test-helpers');

const MyToken =  artifacts.require('MyToken');

contract('MyToken', function (accounts) {
  beforeEach(async function () {

    await singletons.ERC1820Registry(accounts[0]);

    myToken = await MyToken.deployed();
  });

  it("gives the owner of the token 1M tokens",async()=>{

    let balance = await myToken.balanceOf(accounts[0]);

    balance = web3.utils.fromWei(balance,'ether');

    assert.equal(balance,'1000000','Balance should be 1M tokens for contract creator')
  })
});
Enter fullscreen mode Exit fullscreen mode

Step 9. Run following command to test your contract.

truffle test
Enter fullscreen mode Exit fullscreen mode

You should see something like this.

Image description

OpenZeppline should really consider adding such details and simple tutorials in their documentation. Anyways, you can now use this tutorial and modify it as per your needs. You can get the complete project code from the following Github link. If you have any queries feel free to comment below. Adios!
Github Repository

Top comments (0)