Creating your own ERC-20 token on Ethereum no longer requires deep blockchain expertise—thanks to modern development tools like Truffle, OpenZeppelin, and accessible testnets such as Goerli. This step-by-step guide walks you through deploying a fully functional ERC-20 token in under 15 minutes using secure, community-audited smart contracts.
Whether you're building a decentralized app (dApp), launching a community token, or just exploring Web3 development, this tutorial equips you with the foundational skills to get started—fast.
Why This Guide Is Up-to-Date
The Web3 ecosystem evolves rapidly. Many existing tutorials rely on deprecated tools—like the Rinkeby testnet, which was retired in 2022. This guide uses current best practices:
- Goerli testnet instead of outdated networks
- Truffle v5.6.3+ with modern Solidity compiler versions
- Integration with Infura for seamless deployment
- Real-time verification via Etherscan
Let’s dive in.
Project Setup
Before writing any code, ensure your development environment is ready.
Prerequisites
Install Truffle globally using npm:
npm install -g truffle✅ Verify installation: Run truffle version to confirm it's installed correctly.We’ll name our token MyToken for demonstration purposes. Replace it with your desired token name when following along.
Initialize the Project
Create a new Truffle project:
truffle init MyToken && cd MyTokenThis generates the standard Truffle structure:
contracts/: Store Solidity filesmigrations/: Deployment scriptstest/: Unit and integration teststruffle-config.js: Configuration file
Install Dependencies
Install OpenZeppelin Contracts for secure, pre-audited ERC-20 implementation:
npm install @openzeppelin/contractsOpenZeppelin provides battle-tested implementations that prevent common vulnerabilities—critical for production-grade tokens.
👉 Get started with secure blockchain development tools today.
Write Your ERC-20 Token Contract
Navigate to the contracts/ folder and create MyToken.sol.
Solidity Code Explained
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract MyToken is ERC20 {
constructor(
string memory name,
string memory symbol,
uint256 initialSupply
) ERC20(name, symbol) {
require(initialSupply > 0, "Initial supply must be greater than 0");
_mint(msg.sender, initialSupply * 10**18);
}
}Key Concepts:
- SPDX License Identifier: Declares the open-source license (MIT in this case).
- Pragma Version: Ensures compatibility with Solidity 0.8.17+, avoiding breaking changes.
- Inheritance (
is ERC20): Leverages OpenZeppelin’s robust ERC-20 base contract. - _mint(): Securely mints tokens to the deployer’s wallet. Only callable during construction here.
- 18 Decimals: Matches ETH’s precision, enabling fractional transfers (e.g., 0.001 MyToken).
Configure Truffle for Deployment
Update truffle-config.js to support local testing and Goerli deployment.
require("dotenv").config();
const { MNEMONIC, PROJECT_ID } = process.env;
const HDWalletProvider = require("@truffle/hdwallet-provider");
module.exports = {
networks: {
development: {
host: "127.0.0.1",
port: 9545,
network_id: "*",
},
goerli: {
provider: () =>
new HDWalletProvider(
MNEMONIC,
`https://goerli.infura.io/v3/${PROJECT_ID}`
),
network_id: 5,
confirmations: 2,
timeoutBlocks: 200,
skipDryRun: true,
},
},
compilers: {
solc: {
version: "0.8.17",
},
},
};Install Required Packages
npm install @truffle/hdwallet-provider dotenvSet Up Environment Variables
Create a .env file in the root directory:
MNEMONIC="your twelve-word metamask recovery phrase"
PROJECT_ID="your-infura-project-id"🔐 Never commit.envto version control. Add it to.gitignore.
Retrieve Your MetaMask Recovery Phrase
To sign transactions, Truffle needs access to your wallet.
- Open MetaMask browser extension.
- Click the three dots → Settings → Advanced → Show Secret Recovery Phrase.
- Copy the 12-word phrase into
.envasMNEMONIC.
⚠️ Keep this phrase offline and secure. Never share it.
Get an Infura API Key
Infura provides RPC access to Ethereum networks without running your own node.
- Go to infura.io and sign up (free tier available).
- Create a new project → Select Web3 API.
- Choose Goerli from endpoints.
- Copy the URL:
https://goerli.infura.io/v3/YOUR_PROJECT_ID - Paste only the ID into
.envasPROJECT_ID.
Create Migration Script
Migrations automate contract deployment.
Create migrations/1_initial_migration.js:
const MyToken = artifacts.require("MyToken");
module.exports = (deployer) => {
deployer.deploy(MyToken, "MyToken", "MYT", 100000);
};This script:
- References the
MyTokencontract - Passes constructor arguments: name, symbol, initial supply (in whole units)
- Automatically converts supply to wei-scale using
* 10**18internally
Deploy Locally for Testing
Test your setup before going live.
- Start Truffle’s built-in blockchain:
truffle develop- Compile contracts:
compileOutput should show successful compilation and artifact generation.
- Deploy with migration:
migrate --resetUse --reset to redeploy from scratch if testing multiple times.
Interact with Your Token
Once deployed:
token = await MyToken.deployed()
name = await token.name()
symbol = await token.symbol()
decimals = (await token.decimals()).toString()
balance = (await token.balanceOf(accounts[0])).toString()Expected output:
name: "MyToken"symbol: "MYT"decimals: "18"balance: "100000000000000000000000" (i.e., 100,000 × 10¹⁸)
You now have a working ERC-20 token on a local chain!
👉 Speed up your Web3 development workflow with powerful tools.
Deploy to Goerli Testnet
Now deploy publicly so others can interact with your token.
Get Goerli ETH
Switch MetaMask network to Goerli Test Network:
- Enable “Show test networks” in Settings → Advanced
Visit a faucet like goerlifaucet.com, enter your address, and claim test ETH.
Wait for confirmation in MetaMask.
Run Migration on Goerli
Back in your terminal:
truffle migrate --reset --network goerliSuccessful output includes:
- Transaction hash
- Contract address (e.g.,
0x904...D8D) - Gas cost and deployment block
Save the contract address—you’ll need it next.
Verify on Etherscan
Explore your deployed token at:
https://goerli.etherscan.io/address/YOUR_CONTRACT_ADDRESSYou’ll see:
- Token name, symbol, and holder count
- Full transaction history
- Read/write contract functions
Etherscan confirms your token is live and verifiable by anyone.
Add Token to MetaMask
Make your token visible in your wallet.
- In MetaMask, click Import Tokens.
- Paste the contract address.
- Wait for auto-fill of symbol and decimals.
- Click Add Custom Token.
Your balance should appear instantly!
Frequently Asked Questions (FAQ)
Can I change the number of decimals?
Yes! Modify the _mint line to use a different exponent (e.g., 10**6 for 6 decimals). Just ensure consistency across all systems interacting with your token.
Is OpenZeppelin safe to use?
Absolutely. OpenZeppelin Contracts are open-source, widely audited, and used by major protocols like Uniswap and Aave. They follow security-first principles.
What happens if I lose my MNEMONIC?
If someone gains access to your recovery phrase, they control your funds. Always store it securely offline—never in cloud notes or screenshots.
Can I upgrade my token later?
By default, this implementation is immutable. For upgradable contracts, consider OpenZeppelin’s Upgradeable Contracts library—but weigh complexity vs. necessity.
Why use Goerli instead of Sepolia?
Goerli supports both Proof-of-Authority (PoA) and cross-client compatibility, making it ideal for developers testing interoperability. It also has broader tooling support.
How much does deployment cost?
On Goerli, gas is free (test ETH). On mainnet, expect $30–$150 depending on network congestion. You can estimate costs using ethgasstation.info.
Final Thoughts
You’ve just created and deployed a compliant ERC-20 token using industry-standard tools—all in minutes.
From here, consider:
- Adding custom logic (e.g., pausable transfers)
- Writing unit tests with Truffle
- Publishing source code on Etherscan for transparency
Blockchain development has never been more accessible.
👉 Take your next step into Web3 with trusted infrastructure and developer resources.