ERC20 from the ground up
Building Your Own Magic Token: A Beginner’s Guide
Have you ever played a video game where you collect coins or stars? Imagine creating your own special coin that you can share with friends or use in a game. That’s kind of like making a token on the Ethereum blockchain! Let’s learn how to create a simple token, step by step, like a digital piggy bank you can program. 🪙
What is an ERC20 Token?
An ERC20 token is like a magical digital coin that lives on the Ethereum network. The ERC20 standard is a set of rules that every token follows so it can be used in different apps, games, and exchanges — just like how we all agree that a soccer ball is round and can be kicked to score a goal.
Why Create a Token?
Money for games: You can create coins players can earn and spend.
Voting power: People can use tokens to vote on decisions.
Rewards and points: Like collecting stars for doing something awesome!
Where Are Tokens Used?
Uniswap (UNI): Trade tokens like a digital marketplace.
Aave (AAVE): Borrow or lend tokens to earn rewards.
Compound (COMP): Save tokens and earn extra tokens over time!
Let’s Build a Simple Token!
Here’s the magic recipe (code) to create your own token. It’s like telling a robot how your coin should work.
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.28;
contract ERC20 {
string public name;
string public symbol;
uint8 public decimals;
uint256 public totalSupply;
address public owner;
mapping(address => uint256) public balances;
mapping(address => mapping(address => uint256)) public allowances;
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
constructor(string memory _name, string memory _symbol, uint8 _decimals, uint256 _totalSupply) {
name = _name;
symbol = _symbol;
decimals = _decimals;
totalSupply = _totalSupply;
owner = msg.sender;
balances[owner] = _totalSupply;
}
function balanceOf(address account) public view returns (uint256) {
return balances[account];
}
function transfer(address to, uint256 amount) public returns (bool) {
require(to != address(0), "Invalid address");
require(amount > 0, "Amount must be greater than zero");
require(balances[msg.sender] >= amount, "Insufficient balance");
balances[msg.sender] -= amount;
balances[to] += amount;
emit Transfer(msg.sender, to, amount);
return true;
}
function approve(address spender, uint256 amount) public returns (bool) {
require(spender != address(0), "Invalid address");
allowances[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);
return true;
}
function allowance(address _owner, address spender) public view returns (uint256) {
return allowances[_owner][spender];
}
function transferFrom(address from, address to, uint256 amount) public returns (bool) {
require(from != address(0) && to != address(0), "Invalid address");
require(amount > 0, "Amount must be greater than zero");
require(balances[from] >= amount, "Insufficient balance");
require(allowances[from][msg.sender] >= amount, "Allowance exceeded");
allowances[from][msg.sender] -= amount;
balances[from] -= amount;
balances[to] += amount;
emit Transfer(from, to, amount);
return true;
}
}
What Does This Code Do?
Create the token: Name, symbol, and how many coins exist.
Check balances: See how many tokens someone has.
Send tokens: Move tokens from one account to another.
Approve spending: Let someone else spend tokens for you (like giving your friend some game credits).
Testing Your Token
Imagine testing your token like trying out a new board game to make sure the rules work.
import {
time,
loadFixture,
} from "@nomicfoundation/hardhat-toolbox/network-helpers";
import { expect } from "chai";
import hre from "hardhat";
import { Signer } from "ethers";
describe("ERC20", function () {
async function deployErc20() {
const ADDRESS_ZERO = '0x0000000000000000000000000000000000000000'
const [owner, otherAccount] = await hre.ethers.getSigners();
const Token = await hre.ethers.getContractFactory("ERC20");
const token = await Token.deploy("JAYTOKEN", "JAY", 18);
return { owner, otherAccount, ADDRESS_ZERO, token };
}
it("Should deploy with initial supply", async function () {
it("Should deploy the contract", async () => {
const { token, ADDRESS_ZERO } = await deployErc20();
expect(token.target).to.be.not.equal(ADDRESS_ZERO);
});
});
});
Wrap-Up
Creating a token is like inventing your own digital treasure. With just a bit of code, you can build tokens for games, communities, or even start your own mini economy. The possibilities are endless ; so keep learning and dreaming big.