Building a simple token (ERC-20 token tutorial)

Loading

Creating an ERC-20 token is a foundational step in Ethereum blockchain development. ERC-20 is a technical standard for smart contracts on the Ethereum blockchain for implementing tokens. These tokens are interoperable with a wide range of decentralized applications (DApps), wallets, and exchanges that support Ethereum.

This tutorial will guide you through writing and deploying a simple ERC-20 token using Solidity, the Remix IDE, and MetaMask.


Prerequisites

Before starting, ensure you have the following:

  • MetaMask wallet installed and configured
  • Access to Remix IDE (https://remix.ethereum.org/)
  • Basic understanding of Solidity and Ethereum
  • Testnet ETH for deploying the contract (Goerli or Sepolia)

Step 1: Understand the Standard ERC-20 Functions

ERC-20 defines a set of functions and events that a token smart contract must implement. These include:

  • name: The token’s name
  • symbol: A short symbol (e.g., ETH, USDT)
  • decimals: How divisible the token is (commonly 18)
  • totalSupply: The total token supply
  • balanceOf: Returns the balance of a given address
  • transfer: Transfers tokens to a specified address
  • approve: Allows a third party to spend tokens
  • transferFrom: Transfers tokens on behalf of an approved address
  • allowance: Returns how many tokens an address can spend on behalf of the owner

Step 2: Write the ERC-20 Smart Contract

Open Remix IDE and create a new file named MyToken.sol. Paste the following Solidity code:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract MyToken {
string public name = "MyToken";
string public symbol = "MTK";
uint8 public decimals = 18;
uint public totalSupply = 1000000 * 10 ** uint(decimals);

mapping(address => uint256) public balanceOf;
mapping(address => mapping(address => uint256)) public allowance;

constructor() {
balanceOf[msg.sender] = totalSupply;
}

function transfer(address to, uint256 value) public returns (bool success) {
require(balanceOf[msg.sender] >= value, "Insufficient balance.");
balanceOf[msg.sender] -= value;
balanceOf[to] += value;
return true;
}

function approve(address spender, uint256 value) public returns (bool success) {
allowance[msg.sender][spender] = value;
return true;
}

function transferFrom(address from, address to, uint256 value) public returns (bool success) {
require(balanceOf[from] >= value, "Insufficient balance.");
require(allowance[from][msg.sender] >= value, "Allowance exceeded.");
balanceOf[from] -= value;
balanceOf[to] += value;
allowance[from][msg.sender] -= value;
return true;
}
}

Step 3: Compile the Contract

  • In Remix, click on the “Solidity Compiler” tab.
  • Select the appropriate compiler version (for example, 0.8.0 or later).
  • Click “Compile MyToken.sol”.

Step 4: Deploy the Contract

  • Click the “Deploy and Run Transactions” tab.
  • Choose “Injected Web3” as the environment to connect with MetaMask.
  • Ensure you are on a test network like Goerli or Sepolia in MetaMask.
  • Click “Deploy” and approve the transaction in MetaMask.

Step 5: Interact with the Deployed Contract

Once deployed, you can interact with the following functions directly from Remix:

  • balanceOf: Check the balance of any Ethereum address
  • transfer: Send tokens to another wallet address
  • approve and transferFrom: Delegate token spending authority to other addresses

Step 6: Testing with Testnet ETH

To fully test your token:

  1. Use a faucet to obtain test ETH.
  2. Transfer some of your tokens to other addresses.
  3. Use approve and transferFrom to simulate third-party transfers.
  4. Observe changes using balanceOf and allowance.

Security Considerations for Production

If you plan to release a token in a real-world environment:

  • Use the OpenZeppelin ERC-20 implementation, which is professionally audited.
  • Emit events such as Transfer and Approval for transparency and tracking.
  • Add access controls using Ownable or similar mechanisms.
  • Avoid hardcoding critical values unless necessary.
  • Thoroughly audit your smart contract for vulnerabilities.

Alternative: Using OpenZeppelin’s ERC-20 Implementation

A safer and more concise way to build a token is to inherit from OpenZeppelin’s ERC-20 contract:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

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

contract MyToken is ERC20 {
constructor(uint256 initialSupply) ERC20("MyToken", "MTK") {
_mint(msg.sender, initialSupply);
}
}

This version automatically includes all required ERC-20 functions and safety checks.

Leave a Reply

Your email address will not be published. Required fields are marked *