jackofcrypto

Posted on Jan 15, 2022Read on Mirror.xyz

Introduction to Token Standards

Learn about two types of blockchain tokens: fungible and non-fungible. Learn how to use the ERC-20 token standard. Learn how to use the MetaMask digital wallet.

By the end of this post, readers will be able to:

  • Differentiate fungible from non-fungible tokens.
  • Explain that the Ethereum Request for Comments (ERC) standards are official smart contract implementations for various use cases.
  • Implement the ERC-20 standard to create a fungible token by using the OpenZeppelin library.
  • Deploy and test a token that uses the ERC-20 standard by using MetaMask and a Ganache blockchain.

Some tokens represent assets that have interchangeable and exchangeable values. These are called fungible tokens. Tokens that represent fiat currency or cryptocurrency often fall into this category.

Tokens representing stores of value that aren’t directly comparable and interchangeable are called non-fungible tokens, or NFTs. NFTs depend more on which assets someone owns rather than on how many.

Both types have value, but the value of each NFT is unique. This leads to different sets of rules, processes, and implementations for fungible and non-fungible tokens. The smart contracts that create NFTs follow different standards than those that create fungible tokens.

EIPs and ERCs

Developers form standards that outline best practices for the platform to prevent bugs and security vulnerabilities. In Ethereum, these standards are known as Ethereum Improvement Proposals, or EIPs. The Ethereum Foundation officially refers to an EIP as “a design document providing information to the Ethereum community, or describing a new feature for Ethereum or its processes or environment.”

Although there are several categories of EIPs, we’ll focus on Ethereum Request for Comments (ERC). This type of EIP sets standards at the application level. This means that the standards apply to the code for applications, such as smart contracts and tokens.

Most EIPs, including ERCs, follow a similar workflow, which includes the following stages:

  • Work in progress (WIP): An EIP creator formulates an EIP and can ask for input on community forums.
  • ** Draft:** The initial EIP draft and any changes get merged into the Ethereum EIP GitHub repository via a pull request. The EIP must then be implemented or, written as code, progress to the next phase.
  • ** Last Call:** The EIP gets listed on the Ethereum Improvement Proposals website in the Last Call section. If no unaddressed technical complaints or required changes to the source material exist, the EIP will become final. This means that the standard won’t change after this point.
  • ** Final:** The Ethereum blockchain and its participants begin using the processes that the EIP lays out.

Many ERC token standards exist, but we’ll focus on two of the most popular:

ERC-20 Standard

We use the ERC-20 standard for fungible Ethereum tokens that store value. The ERC-20 standard defines rules for how the tokens get used, how transactions get made, and how new tokens get created (or minted).

The ERC-20 standard serves as the basis for many cryptocurrencies and coins, especially stablecoins, that exist today. These include Chainlink (LINK), Wrapped Bitcoin (WBTC), Binance Coin (BNB), USD Coin (USDC), and Dai (DAI) for example.

The OpenZeppelin library provides a wide variety of contracts that relate to the ERC-20 token standard. Each of the OpenZeppelin ERC-20 contracts is designed to accomplish something slightly different. And, we can further customize each contract for our particular purposes.

The Ethereum ERC-20 standard defines some mandatory functions for a fungible token contract, including _transfer, _mint, balanceOf, and totalSupply. These functions provide critical functionality for any ERC-20 token.

We want our ArcadeToken contract to become a version of the OpenZeppelin ERC20 contract. But, we also want ArcadeToken to include the optional functions from ERC20Detailed. So, we’ll import and inherit both the ERC20 and ERC20Detailed contracts. This will tell Solidity that ArcadeToken is a version of the ERC20 contract and that it’s also a version of the ERC20Detailed contract.

pragma solidity ^0.5.0;

import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v2.5.0/contracts/token/ERC20/ERC20.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v2.5.0/contracts/token/ERC20/ERC20Detailed.sol";

contract ArcadeToken is ERC20, ERC20Detailed {

}

After we save or compile our contract in the Remix IDE, the ERC20.sol and ERC20Detailed.sol contracts that we imported will get downloaded and listed in the Remix files list.

Navigate to the constructor function inside the ERC20Detailed contract. This function should appear as follows:

constructor (string memory name, string memory symbol, uint8 decimals) public {
     _name = name;
     _symbol = symbol;
     _decimals = decimals;
 }

The constructor is a programming technique that many programming languages use. With constructors, you can quickly customize code with your own initial values.

  • The constructor creates a new contract by using the supplied parameters. Using a constructor simplifies the process of creating custom versions of the ERC20Detailed contract. The name parameter contains the human-friendly name of the token, the symbol parameter contains the ticker symbol of the token, and the decimals parameter contains the number of decimal places that this token will use.

Using decimal places allows customers to purchase or transfer fractions of a token.

  • ETH uses 18 decimal places. This means that we can divide one ether into increments of 10^18 (that is, increments of 1 followed by 18 zeros). So, the smallest denomination of an ETH is one divided by 10^18, which we call a wei.
  • Most tokens use 18 decimal places. This is because ether uses 18 decimal places. And, using the same number of decimal places simplifies the conversion between ether and tokens.

All ETH transactions get conducted in wei. Similarly, all token transactions get conducted in the smallest denomination of a token, which OpenZeppelin calls a bit.

The final token contract appears as follows:

pragma solidity ^0.5.0;

import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v2.5.0/contracts/token/ERC20/ERC20.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v2.5.0/contracts/token/ERC20/ERC20Detailed.sol";

contract ArcadeToken is ERC20, ERC20Detailed {
    address payable owner;

    modifier onlyOwner {
        require(msg.sender == owner, "You do not have permission to mint these tokens!");
        _;
    }

    constructor(uint initial_supply) ERC20Detailed("ArcadeToken", "ARCD", 18) public {
        owner = msg.sender;
        _mint(owner, initial_supply);
    }

    function mint(address recipient, uint amount) public onlyOwner {
        _mint(recipient, amount);
    }
}

Introducing MetaMask

To deploy and test our contract, we will use the test blockchain application Ganache and an integrated wallet called MetaMask. The purpose of this section is to get familiarized with the high-level integration among Ganache, MetaMask, and Remix.

MetaMask is a wallet that people can use to interact with the Ethereum blockchain or with various Ethereum-related test blockchains. First add a custom Ganache network in MetaMask. Include the information below:

  • Network Name: Ganache
  • New RPC URL: The RPC URL from Ganache, which is HTTP://127.0.0.1:7545
  • Chain ID: The value 1337, which is specific to Ganache.

Add Network in MetaMask

We can import an account from Ganache into MetaMask. To do that, we first click the My Accounts button in Metamask, and then on the menu that displays, we select Import Account. We make sure that Private Key is selected on the Select Type drop-down menu. We then copy the private key from the Account Information page in Ganache and paste it into the Paste your private key string here box. We then click the Import button.

Open the deployment page in Remix, and then deploy the contract using by the Injected Web environment. Once we select Injected Web3, the MetaMask Chrome extension automatically opens and displays accounts from which we can choose for testing. Select each of the accounts that you just imported from Ganache to import into Remix.

In the Deploy & Run Transactions pane, in the initial_supply box, type an arbitrary amount. This sets the value of the initial_supply constructor parameter. Then click the transact button.

Once the contract is deployed in Remix, navigate back to Ganache, and then click the Transactions button (which appears along the top of the page). The Transactions page opens and displays the transaction details. This includes the transaction hash, the account address, and the created contract address, as the following image shows:

Transactions in Ganache

To summarize this section:

  • We use Remix to develop, compile, deploy, and test the contract operations.
  • Ganache mimics the Ethereum blockchain but in the local environment. Ganache creates the account that we use to test the application. It also creates a record of the transactions that occur in the contract.
  • MetaMask is the wallet. It functions as the go-between, routing information between Ganache and Remix. MetaMask stores the information that’s associated with each account. This includes the private key, the address, the ether balance, and the balance of other tokens that the account has purchased.

Until next time, here’s a twitter thread summary of this post:

https://twitter.com/jackofcrypto/status/1482501267335172097?s=20