How To Create ERC-20 Token Using Openzeppelin and Truffle: A Beginner Guide
Table of contents
- Introduction
- Prerequisites
- Create Workspace
- Install Dependencies
- Create Truffle Project
- Scaffold Token Contract
- Creating ObiDatti ($OBD) Token
- Scaffold ObiDatti ($OBD) Migration
- Creating ObiDatti ($OBD) Migration
- Compiling ObiDatti ($OBD) Smart Contract
- Deploying ObiDatti ($OBD) On Testnet (Goerli)
- Verifying ObiDatti ($OBD)
- Conclusion
- Useful links
Introduction
ERC-20 (Ethereum Request for Comment 20) is a standard for creating fungible tokens on the Blockchain Network. In November 2015, the ERC-20 standard was proposed by Vitalik Buterin and Fabian Vogelsteller as EIP-20.
In this tutorial, you will learn how to build and deploy an ERC-20 token on the Ethereum network.
Upon completion of this tutorial, you will have a fully compliant ERC-20 token.
It is recommended that you proceed with caution and attentiveness throughout the tutorial to achieve the desired outcome.
Let's get started.
Prerequisites
To complete this tutorial, you will need:
Node.js installed on your PC.
Visual Studio Code or your favorite editor.
Infura account.
Etherscan.io developer account.
Basic knowledge of Solidity. You can look at the official introduction to a smart contract.
Create Workspace
Open a terminal to create your working folder with the following commands:
# create directory
$ mkdir ObiDatti
# move into the ObiDatti directory
$ cd ObiDatti
# initialize node.js project
$ npm init -y
Install Dependencies
Run the following commands to install the packages needed for this tutorial:
truffle: A development environment, testing framework, and asset pipeline for blockchains using the Ethereum Virtual Machine (EVM), aiming to make life as a developer easier.
openzeppelin/contracts: A library for secure smart contract development Build on a solid foundation of community-vetted code.
truffle/hdwallet-provider: A simple library that uses private keys, mnemonics, or phrases (12 or 24 words) to sign transactions (deployment).
truffle-plugin-verify: A truffle plugin for verifying smart contracts without leaving your terminal.
dotenv: A library that loads environment variables from a .env
file into process.env
$ npm i -g truffle
$ npm i @openzeppelin/contracts @truffle/hdwallet-provider truffle-plugin-verify@0.5.28 dotenv
Create Truffle Project
You will need to initialize a new truffle project using the command below:
$ truffle init
# Init successful, sweet!
# Try our scaffold commands to get started:
# $ truffle create contract YourContractName # scaffold a contract
# $ truffle create test YourTestName # scaffold a test
# http://trufflesuite.com/docs
Scaffold Token Contract
After the creation of the truffle project, it is necessary to scaffold the ERC-20 smart contract through the execution of the following command:
$ truffle create contract ObiDatti
Creating ObiDatti ($OBD) Token
The next step is to create an ERC-20 token named ObiDatti using the Openzeppelin framework. Open the filecontracts/ObiDatti.sol
and paste the following code into it.
// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.9.0;
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 ObiDatti is ERC20, ERC20Burnable, Pausable, Ownable {
// this execute only on deployment i.e it runs only once.
constructor() ERC20("ObiDatti", "OBD") {
// minting 1,000,000 to msg.sender (ObiDatti deployer)
_mint(msg.sender, 1000000 * 10**decimals());
}
/// @dev
/// mint(address, uint256) function mints new tokens to specific
/// address `to`
/// NB: Only callable by ObiDatti deployer (onlyOwner)
function mint(address to, uint256 amount) public onlyOwner {
_mint(to, amount);
}
/// @dev
/// pause() function pauses token transfer on ObiDatti
/// NB: Only callable by ObiDatti deployer (onlyOwner)
function pause() public onlyOwner {
_pause();
}
/// @dev
/// unpause() function un-pauses token transfer on ObiDatti
/// NB: Only callable by ObiDatti deployer (onlyOwner)
function unpause() public onlyOwner {
_unpause();
}
/// @dev
/// _beforeTokenTransfer() function override method in `ERC20` i.e
/// super._beforeTokenTransfer(from, to, amount) making transfer of
/// ObiDatti token only possible `whenNotPaused`.
function _beforeTokenTransfer(
address from,
address to,
uint256 amount
) internal override whenNotPaused {
super._beforeTokenTransfer(from, to, amount);
}
}
The contract ObiDatti
extends OpenzeppelinERC20, ERC20Burnable, Pausable, Ownable
to create mintable, burnable, and pausable ERC-20 tokens (ObiDatti).
Scaffold ObiDatti ($OBD) Migration
After the creation of the ObiDatti smart contract, we would need to create a migration file for either test-net or main-net deployment:
$ truffle create migration ObiDatti
Creating ObiDatti ($OBD) Migration
Open the file migrations/xxxxx_obi_datti.js
and paste the following code into it.
const ObiDatti = artifacts.require('ObiDatti')
module.exports = function (_deployer) {
// .deploy(ObiDatti) call ObiDatti constructor and deploy the
// smart contract to the chosen network.
_deployer.deploy(ObiDatti)
}
Compiling ObiDatti ($OBD) Smart Contract
To compile the contract, open the terminal and run the following command:
$ truffle compile
# Compiling your contracts...
# ===========================
# > Compiling @openzeppelin\contracts\access\Ownable.sol
# > Compiling @openzeppelin\contracts\security\Pausable.sol
# > Compiling @openzeppelin\contracts\token\ERC20\ERC20.sol
# > Compiling @openzeppelin\contracts\token\ERC20\IERC20.sol
# > Compiling @openzeppelin\contracts\token\ERC20\extensions\ERC20Burnable.sol
# > Compiling @openzeppelin\contracts\token\ERC20\extensions\IERC20Metadata.sol
# > Compiling @openzeppelin\contracts\utils\Context.sol
# > Compiling .\contracts\ObiDatti.sol
# > Artifacts written to ..\ObiDatti\build\contracts
# > Compiled successfully using:
# - solc: 0.8.18+commit.87f61d96.Emscripten.clang
After a successful compilation, open the build/
folder to check all the contract artifacts containing the contract name, bytecode, ABI, compiler version, deployment details, etc.
Deploying ObiDatti ($OBD) On Testnet (Goerli)
Preparing Environment Variables
Create .env
file in the root folder and paste the following code into it.
INFURA_API_URL="https://goerli.infura.io/v3/{INFURA_KEY}"
MNEMONIC="{PHRASE}"
ETHERSCAN_API_KEY="{ETHERSCAN_KEY}"
INFURA_API_URL: Log into the Infura account you created earlier and click on CREATE NEW KEY then select Web3 API as network and ObiDatti as name, then click on CREATE. Copy and paste your API key into {INFURA_KEY}
.
MNEMONIC: Install Metamask from Google Chrome Web Store. After installation, start the extension and create a new wallet. Copy and paste your 12 recovery phrases or words one after the other (with whitespace) into {PHRASE}
.
ETHERSCAN_API_KEY: Log into the etherscan.io account you created earlier and click on API Keys > +Add > Enter the app name and click on Create New API Key. Copy and paste your API key token into {ETHERSCAN_KEY}
.
Updating Truffle Configuration
Open the file truffle-config.js
and paste the following code into it.
const HDWalletProvider = require('@truffle/hdwallet-provider')
const dotenv = require('dotenv')
// load env variables
dotenv.config()
// destructure INFURA_API_URL, MNEMONIC, ETHERSCAN_API_KEY
const { INFURA_API_URL, MNEMONIC, ETHERSCAN_API_KEY } = process.env
module.exports = {
/**
* Networks define how you connect to your ethereum client and let you set the
* defaults web3 uses to send transactions. If you don't specify one truffle
* will spin up a managed Ganache instance for you on port 9545 when you
* run `develop` or `test`. You can ask a truffle command to use a specific
* network from the command line, e.g
*
* $ truffle test --network <network-name>
*/
networks: {
// Useful for deploying to a public network.
// Note: It's important to wrap the provider as a function to ensure truffle uses a new provider every time.
goerli: {
provider: () => new HDWalletProvider(MNEMONIC, INFURA_API_URL),
network_id: 5, // Goerli's id
gas: 5500000,
networkCheckTimeoutnetworkCheckTimeout: 10000,
confirmations: 2, // # of confirmations to wait between deployments. (default: 0)
timeoutBlocks: 200, // # of blocks before a deployment times out (minimum/default: 50)
skipDryRun: true, // Skip dry run before migrations? (default: false for public nets )
},
},
// Configure your compilers
compilers: {
solc: {
version: '0.8.18',
},
},
// truffle-plugin-verify configurations
plugins: ['truffle-plugin-verify'],
api_keys: {
etherscan: ETHERSCAN_API_KEY,
},
}
Getting Some Test ETH For Deployment
Faucets are the easiest way of getting test ETH at zero cost. Open the MetaMask extension you installed previously and copy your wallet address. Go to QuickNode Goerli Faucet and paste the address to get 0.1 ETH for free.
Deploying ObiDatti ($OBD)
Open a terminal and run the following command to deploy the ObiDatti contract to the Goerli test network.
$ truffle migrate --network goerli
# Starting migrations...
# ======================
# > Network name: 'goerli'
# > Network id: 5
# > Block gas limit: 30000000 (0x1c9c380)
# 1676641071_obi_datti.js
# =======================
# Deploying 'ObiDatti'
# --------------------
# > transaction hash: 0x706ffc53a35b4e8bbb9edaf207ca517031651d7e69869160072d7671f83fe757
# > Blocks: 1 Seconds: 9
# > contract address: 0xECE49A968924642639429364865b91b95b556E13
# > block number: 8513220
# > block timestamp: 1676722824
# > account: 0x611ac347131c013D5f24ae0189AEfAB8a4c823c2
# > balance: 0.095303866907851373
# > gas used: 1878451 (0x1ca9b3)
# > gas price: 2.500002977 gwei
# > value sent: 0 ETH
# > total cost: 0.004696133092148627 ETH
# Pausing for 2 confirmations...
# -------------------------------
# > confirmation number: 1 (block: 8513221)
# > confirmation number: 2 (block: 8513222)
# > Saving artifacts
# -------------------------------------
# > Total cost: 0.004696133092148627 ETH
# Summary
# =======
# > Total deployments: 1
# > Final cost: 0.004696133092148627 ETH
Verifying ObiDatti ($OBD)
Open a terminal and run the following command to verify the ObiDatti contract.
$ truffle run verify ObiDatti --network goerli
# Verifying ObiDatti
# Pass - Verified: https://goerli.etherscan.io/address/0xECE49A968924642639429364865b91b95b556E13#code
# Successfully verified 1 contract(s).
Conclusion
In this article, we have created a mintable, burnable, and pausable token ($OBD) on Ethereum Goerli Network. We have also verified the smart contract for transparency.
$OBD Contract Address: https://goerli.etherscan.io/address/0xECE49A968924642639429364865b91b95b556E13
$OBD Code: https://goerli.etherscan.io/address/0xECE49A968924642639429364865b91b95b556E13#code
$OBD Deployer (with 1,000,000 $OBD): https://goerli.etherscan.io/address/0x611ac347131c013D5f24ae0189AEfAB8a4c823c2
Thanks for reading ❤️
Useful links
Subscribe to my newsletter
Read articles from Obafunso Ridwan directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Obafunso Ridwan
Obafunso Ridwan
I am Obafunso Ridwan Adebayo, A Software Engineer from Lagos, Nigeria.