Build and Deploy Your Own ERC20 Token Using Hardhat and Solidity

·

Creating your own cryptocurrency token on the Ethereum blockchain is no longer reserved for advanced developers. With modern development tools like Hardhat, Solidity, and ethers.js, anyone with basic programming knowledge can deploy a fully functional ERC20 token in minutes. This guide walks you through the complete process—from setting up your environment to deploying a customizable token and interacting with it via a React-based frontend.

Whether you're exploring blockchain for educational purposes or prototyping a decentralized application (dApp), this hands-on tutorial provides everything you need to get started—safely and locally.


Why Create a Custom ERC20 Token?

ERC20 is the most widely adopted standard for fungible tokens on Ethereum. It defines a set of rules that ensure compatibility across wallets, exchanges, and smart contracts. By building your own token, you gain practical insight into:

This project uses no mainnet funds and runs entirely on a local test environment—perfect for learning without risk.

👉 Start building secure blockchain applications today with trusted tools.


Step 1: Initialize Your Development Environment

Before writing any code, set up a clean Node.js project with Hardhat—a powerful Ethereum development environment used by professionals.

npm init -y
npm install --save-dev hardhat
npx hardhat

Follow the prompts to create a new Hardhat project. This generates essential configuration files and directory structure, including contracts/, scripts/, and hardhat.config.js.

Hardhat compiles, tests, and deploys smart contracts while simulating a full Ethereum network locally. It’s ideal for rapid iteration and debugging.


Step 2: Write Your ERC20 Token Contract in Solidity

Navigate to the contracts/ folder and create Fool.sol. This contract implements a basic ERC20 token named "Fool" with symbol "FOOL".

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

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
import "@openzeppelin/contracts/security/Pausable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract Fool is ERC20, ERC20Burnable, Pausable, Ownable {
    constructor() ERC20("Fool", "FOOL") {
        _mint(msg.sender, 100000000 * 10 ** decimals());
    }

    function pause() public onlyOwner {
        _pause();
    }

    function unpause() public onlyOwner {
        _unpause();
    }

    function mint(address to, uint256 amount) public onlyOwner {
        _mint(to, amount);
    }

    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal override whenNotPaused {
        super._beforeTokenTransfer(from, to, amount);
    }
}

Understanding Key Inherited Contracts

The initial supply of 100 million tokens is minted to the deployer’s wallet upon creation.


Step 3: Compile the Smart Contract

Run the built-in compile task:

npx hardhat compile

Hardhat automatically detects .sol files and outputs compiled artifacts into the artifacts/ directory. These JSON files contain ABI definitions needed for frontend interaction.


Step 4: Deploy the Token Locally

Create scripts/deploy.js to automate deployment:

const hre = require("hardhat");

async function main() {
  const [owner] = await hre.ethers.getSigners();
  console.log("Deploying from address:", owner.address);

  const Fool = await hre.ethers.getContractFactory("Fool");
  const fool = await Fool.deploy();
  await fool.deployed();

  console.log("Fool Token deployed to:", fool.address);
}

main()
  .then(() => process.exit(0))
  .catch((error) => {
    console.error(error);
    process.exit(1);
  });

Start a local node in one terminal:

npx hardhat node

Then deploy the contract in another:

npx hardhat run --network localhost scripts/deploy.js

You’ll see output confirming deployment on chain ID 31337 with a generated contract address.

🔐 Security Note: All private keys and addresses in this tutorial are publicly known test accounts. Never use them on mainnet.

Step 5: Interact With Your Token Using a React Frontend

To visualize interactions, create a simple dApp interface using React.

Generate the frontend:

npx create-react-app web --template typescript
cd web
npm install ethers antd react-json-view

Add .env with environment variables:

REACT_APP_CONTARCT_ADDRESS=0x5FbDB2315678afecb367f032d93F642f64180aa3
REACT_APP_DEPLOYER=0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266
REACT_APP_DEPLOYER_PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
REACT_APP_RECIVER=0x70997970c51812dc3a010c7d01b50e0d17dc79c8
REACT_APP_RECIVER_PRIVATE_KEY=0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d

Replace App.tsx with the provided UI code to display token data, balances, and enable transfers.

Launch the app:

npm run start

Visit http://localhost:3000 to send tokens between accounts and view transaction logs in real time.

👉 Explore how leading platforms handle secure blockchain interactions.


Core Keywords for Blockchain Developers

This guide integrates key SEO-friendly terms naturally throughout:

These keywords reflect high-intent search queries from developers seeking actionable tutorials.


Frequently Asked Questions

Can I deploy this token on the Ethereum mainnet?

Yes—but first test thoroughly on Goerli or Sepolia testnets. Update hardhat.config.js with an Alchemy or Infura RPC URL and sign transactions with a secure wallet like MetaMask.

What is the purpose of the Pausable extension?

It allows the contract owner to temporarily freeze all token transfers. This is useful during security incidents or protocol upgrades.

How do I prevent unauthorized minting?

By using onlyOwner modifiers, only the original deployer can call mint(). Ownership can be transferred or renounced using OpenZeppelin’s Ownable methods.

Is it safe to expose private keys in the frontend?

Only in local development! Never commit real keys to version control. Use wallet connection libraries like WalletConnect or Ethers in production.

How can I view my token in MetaMask?

After deployment, manually add the token using its contract address, symbol ("FOOL"), and decimals (18).

Can I customize the total supply?

Absolutely. Modify the _mint() amount in the constructor. For example, change 100000000 * 10 ** decimals() to any desired value.


Final Notes and Best Practices

Every time you restart your local node:

For further learning, explore:

As you progress, consider creating NFTs (ERC721), staking dApps, or integrating Chainlink oracles.

👉 Take your blockchain skills further with advanced tools and resources.