OpenZeppelin ERC777 Token Quick Tutorial on Local Testnet (Ganache/Geth)
Tags: blockchain, ethereum, erc20, erc777
Published: 2022-01-26 21:04:23

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.
```

**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
```
**Step 2**. Initialize NPM and truffle inside the directory.
```
npm init
truffle init
```
**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
    }
}
```
**Step 4**. Install following packages using NPM.
```
npm install @openzeppelin/contracts
npm install --save-dev @openzeppelin/test-helpers
```
**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()), "", "");
    }
}
}
```
**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, []);
};
```
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')
  })
});
```
**Step 9**. Run following command to test your contract.
```
truffle test
```
You should see something like this.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1wjh84fl5nt22b77fwtt.png)

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](https://github.com/dearzubi/OpenZepplineERC777Tutorial
)