Want to make your own ERC-20 token? Here's how in 5 quick steps:
Here's what you need:
Quick tip: Use OpenZeppelin's ERC20 token standard. It's secure and trusted.
Here's a basic ERC-20 token contract:
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract MyToken is ERC20 {
constructor() ERC20("MyToken", "MTK") {
_mint(msg.sender, 1000000 * 10 ** decimals());
}
}
This creates a token called "MyToken" with the symbol "MTK" and mints 1 million tokens to you.
Step | What to do |
---|---|
1. Set up | Install tools, set up test blockchain, get a Web3 wallet |
2. Write contract | Use OpenZeppelin, set token details |
3. Test | Compile, run tests, fix issues |
4. Deploy | Pick a test network, run deployment script |
5. Use | Add to wallet, try functions, track activity |
Remember: Test thoroughly and prioritize security to avoid costly mistakes.
Before you create your ERC-20 token, you'll need a few things:
You should know:
Pro tip: Use OpenZeppelin's ERC20 token standard. It's secure and widely trusted.
Creating an ERC-20 token starts with setting up your dev environment. Here's what you need to do:
Go with Hardhat or Truffle. Hardhat's newer and gets regular updates. Truffle's been around longer but updates are slower.
For Hardhat:
npm install --save-dev hardhat
npx hardhat
For Truffle:
npm install -g truffle
truffle init
Ganache is your go-to for a local Ethereum blockchain. Here's how:
npm install -g ganache-cli
ganache-cli
Boom! You've got 10 Ethereum accounts with 100 test ETH each.
MetaMask's the big player here. It's got about 21 million monthly active users. To set it up:
"The development process involves writing and deploying an Ethereum smart contract, which ensures that a token behaves in a predictable manner, facilitating transactions, managing balances, and interacting with other smart contracts and dApps."
NEVER share your MetaMask seed phrase. Keep it safe!
Time to create your ERC-20 token contract. We'll use OpenZeppelin to keep things simple and standard.
Make a new Solidity file (like MyToken.sol
) and import OpenZeppelin's ERC20 contract:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract MyToken is ERC20 {
constructor() ERC20("MyToken", "MTK") {
_mint(msg.sender, 1000000 * 10 ** decimals());
}
}
This sets up a token named "MyToken" (symbol: "MTK") and mints 1 million tokens to you.
OpenZeppelin's ERC20 contract gives you all the standard functions:
Function | What it does |
---|---|
totalSupply() | Shows total tokens |
balanceOf(address) | Checks an address's balance |
transfer(address, uint256) | Sends tokens |
approve(address, uint256) | Allows spending |
transferFrom(address, address, uint256) | Moves tokens between addresses |
Want to mint more tokens later? Add this:
import "@openzeppelin/contracts/access/Ownable.sol";
contract MyToken is ERC20, Ownable {
// ... constructor ...
function mint(address to, uint256 amount) public onlyOwner {
_mint(to, amount);
}
}
This lets you (the owner) create new tokens anytime.
That's it! You've got a basic, standard-compliant ERC-20 token with a minting option.
You've written your ERC-20 token contract. Now, let's make sure it works.
Compile your contract using the Solidity compiler:
solc --bin MyToken.sol
For more details:
solc -o outputDirectory --bin --ast-compact-json --asm MyToken.sol
Want to reduce gas costs? Use the optimizer:
solc --optimize --bin MyToken.sol
Using Remix IDE? Just hit Ctrl + S to compile. Look for the green checkmark.
Testing is a MUST. Use frameworks like Forge, Hardhat, or Truffle.
Here's a simple Hardhat test:
const { expect } = require("chai");
describe("MyToken", function () {
it("Should mint initial supply to deployer", async function () {
const [owner] = await ethers.getSigners();
const MyToken = await ethers.getContractFactory("MyToken");
const myToken = await MyToken.deploy();
const ownerBalance = await myToken.balanceOf(owner.address);
expect(await myToken.totalSupply()).to.equal(ownerBalance);
});
});
Run it with npx hardhat test
.
Got problems? Here's what to do:
Common issues? Wrong compiler version, missing semicolons, or function logic errors.
Fun fact: OpenZeppelin's ERC-20 test suite has 158 unit tests. That's a LOT of testing!
Remember: Test, test, and test again. It's the key to a solid ERC-20 token.
You've got your ERC-20 token contract ready and tested. Now, let's put it on a blockchain.
For testing, deploy on a test network first. We'll use Sepolia in this guide.
Test Network | Uses |
---|---|
Sepolia | SepoliaETH |
Goerli | GoerliETH |
Mumbai | Test MATIC |
1. Install Hardhat:
yarn add hardhat @nomiclabs/hardhat-waffle @nomiclabs/hardhat-ethers ethers ethereum-waffle
2. Initialize Hardhat:
npx hardhat
3. Update hardhat.config.js
:
module.exports = {
networks: {
sepolia: {
url: "https://sepolia.infura.io/v3/YOUR-PROJECT-ID",
accounts: ["YOUR-PRIVATE-KEY"]
}
}
};
Replace YOUR-PROJECT-ID
and YOUR-PRIVATE-KEY
with your actual details.
1. Create deploy.js
in the scripts
folder:
async function main() {
const [deployer] = await ethers.getSigners();
console.log("Deploying with account:", deployer.address);
const Token = await ethers.getContractFactory("MyToken");
const token = await Token.deploy();
console.log("Token address:", token.address);
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
2. Deploy your token:
npx hardhat run scripts/deploy.js --network sepolia
3. Save the token address output. You'll need it later.
1. Head to Sepolia Etherscan.
2. Search for your token address.
3. Review the contract details.
Want to make your contract's code public? Click "Contract", then "Verify and Publish". Follow the steps to upload your source code.
You've deployed your ERC-20 token. Now what? Let's get it up and running.
First, add your token to MetaMask:
Time to test drive your token:
Check your balance:
balanceOf(your_address)
. Should match your initial supply.Send some tokens:
Play with allowances:
approve()
to let another address spend your tokenstransferFrom()
to move tokens between addressesKeep an eye on your token:
Use Etherscan Sepolia Explorer:
Set up alerts for big transfers or specific wallet activities
Watch holder stats:
Let's recap how we made your ERC-20 token:
1. Set Up
We got Ethereum tools, a test blockchain, and a Web3 wallet ready.
2. Write the Contract
We used OpenZeppelin's ERC20 contract to set token details and add functions.
3. Test It
We compiled, tested, and fixed any issues.
4. Deploy
We picked a test network, set up deployment, ran the script, and checked the contract.
5. Use It
We added the token to our wallet, tried its functions, and tracked activity.
Creating a token is just step one. Here's why security matters:
"In 2016, the DAO hack led to a $60 million theft due to a smart contract flaw."
To avoid this:
Your token's live. Now you can:
Remember: smart contracts are powerful, but they need ongoing attention to stay secure and useful.
Creating an ERC-20 token isn't always smooth sailing. Here are some issues you might run into and how to fix them:
ERC-20's transfer()
and transferFrom()
don't revert on failure. Fix? Use OpenZeppelin's SafeERC20 library. It adds checks to make sure transfers work right.
Messing up allowance settings can lead to double-spending. The fix? Add increaseAllowance
and decreaseAllowance
functions. This stops exploits when changing allowances.
Some tokens take fees on transfer, causing balance mix-ups. Always check balances before and after transfers to catch any fees.
Users sometimes send tokens to contracts that can't handle them. Design your contract to say "no thanks" to incoming ERC-20 tokens if it's not built for them.
Issue | Potential Loss | Fix |
---|---|---|
Sending to wrong contracts | $11+ million (March 2023) | Make contracts reject tokens |
Double-spending | Varies | Use allowance increase/decrease |
Fee-on-transfer issues | Transaction amount | Check balances pre/post-transfer |
Code not compiling? Run npx hardhat compile
. Red text means errors, yellow means warnings. Make sure your Solidity version matches hardhat.config.js
.
Can't deploy because you're short on ETH? Fill up your MetaMask wallet with enough ETH for your network (mainnet or testnet).
Creating an ERC20 token isn't rocket science. Here's what you need to do:
Here's a simple Solidity snippet to get you started:
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract MyToken is ERC20 {
constructor() ERC20("MyToken", "MT") {
_mint(msg.sender, 1000000 * (10 ** uint256(decimals())));
}
}
This code creates a token called "MyToken" with the symbol "MT". It mints 1 million tokens to whoever deploys the contract.
Deploying your ERC20 token is pretty straightforward:
You'll get a contract address after deployment. Use a block explorer to check it out and play with your new token.
To make your token ERC-20 compliant, you need these functions:
Function | What it does |
---|---|
totalSupply | Shows total token supply |
balanceOf | Checks an account's balance |
transfer | Moves tokens between accounts |
transferFrom | Lets approved parties transfer tokens |
approve | Allows spending by another account |
allowance | Shows how much a spender can use |
The easiest way? Use OpenZeppelin's ERC20 contract. Just import it:
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
ERC20 is the go-to standard for fungible tokens on Ethereum. It's like a rulebook that tokens follow to play nice with wallets, exchanges, and other smart contracts.
What's cool about ERC20:
Want to create an ERC20 token with Solidity? Here's how:
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract MyToken is ERC20 {
constructor() ERC20("MyToken", "MT") {
_mint(msg.sender, 1000000 * (10 ** uint256(decimals())));
}
}