
OpenZeppelin ERC20 Token Creation and Deployment is a powerful tool for developers.
Using OpenZeppelin's ERC20 contract, you can create a token with a name, symbol, and a total supply of 1 billion tokens.
To deploy the token, you'll need to create a new instance of the ERC20 contract, specifying the token's name, symbol, and total supply.
You can then deploy the contract to the Ethereum blockchain using a tool like Remix or Truffle.
A fresh viewpoint: List of Erc 20 Tokens
Creating an ERC-20 Token
Creating an ERC-20 Token can be a daunting task, but with the right tools and knowledge, it's achievable. You have two options: Start from scratch and code it yourself, or use OpenZeppelin's collection of secure and tested smart contracts as building blocks.
Using OpenZeppelin's contracts minimizes risk by leveraging "battle-tested libraries" of smart contracts for Ethereum and other blockchains. This approach is highly recommended.
To create an ERC-20 token, you'll need to create a file within the contracts/ directory called MyToken.sol. This file will contain the Solidity code for your token.
The MyToken.sol file should inherit from the OpenZeppelin ERC20 contract using the is keyword. This ensures that your token inherits all the necessary functionality from the ERC20 contract.
The constructor in MyToken.sol takes in the name, symbol, and initialSupply, which will be passed in from the deployer later. This is where you'll set the initial supply of your token.
To issue the tokens, you'll use the _mint function, which has been inherited from OpenZeppelin. This function takes into account the balance with 18 decimals, as decimals are not supported by Solidity and the EVM. This is done to represent the balance in a way that's similar to how 1 ETH is represented by 10^18 of its natural unit (1 Ether = 1,000,000,000,000,000,000 Wei).
Here's a breakdown of the key components of the MyToken.sol file:
- The contract inherits from the OpenZeppelin ERC20 contract using the is keyword.
- The constructor takes in the name, symbol, and initialSupply.
- The _mint function is used to issue the tokens, taking into account the balance with 18 decimals.
By following these steps and using OpenZeppelin's contracts, you can create a secure and functional ERC-20 token.
ERC20 Standard
The ERC20 standard is a token standard that defines six mandatory and three optional functions for token interaction. It's a widely adopted standard in the Ethereum ecosystem.
OpenZeppelin's ERC20 contract already implements these six mandatory functions, including totalSupply, balanceOf, transfer, approve, allowance, and transferFrom. This makes it easy for developers to integrate secure token functionality by inheriting from ERC20.
The logic for each of these functions is already written and tested, so developers can focus on other aspects of their project. The ERC20 contract provides a solid foundation for building token-based applications.
Developers can also customize the optional functionality, including the name, symbol, and decimals functions, while inheriting the ERC20 contract. For instance, the token's name and symbol can be specified in the constructor.
Here are the six mandatory functions implemented by OpenZeppelin's ERC20 contract:
- totalSupply
- balanceOf
- transfer
- approve
- allowance
- transferFrom
Token Creation
Creating an ERC20 token with OpenZeppelin is a straightforward process, but there are two main options to consider: starting from scratch or using the library's battle-tested smart contracts as building blocks.
Option 2 is highly recommended, as it minimizes risk and provides a solid foundation for your token.
To get started, you'll need to create a new file within the `contracts/` directory, which is where you'll store your Solidity contracts.
The file should be named `MyToken.sol` and will contain the contract code.
The contract will inherit from the OpenZeppelin ERC20 contract using the `is` keyword, which is a way of extending the functionality of an existing contract.
The constructor will take in the name, symbol, and initial supply, which will be passed in from the deployer later.
The contract will then use the `_mint` function to issue the tokens, which is a method inherited from OpenZeppelin.
The initial supply is represented as `initialSupply * 10**18`, which is necessary because decimals are not supported by Solidity and the EVM.
Here's a summary of the key components of the contract code:
Token Functionality
Token functionality is key to a successful ERC20 token. The OpenZeppelin implementation includes some functions that are not defined by the ERC20 standard, such as increaseAllowance and decreaseAllowance, which allow for better manipulation of the _allowance variable.
The _burn function is another important feature, which deducts tokens from an account balance and the contract's total supply. Burned tokens are transferred to address zero, and the Transfer event has address zero as the recipient.
The OpenZeppelin implementation also includes the mint function, which allows the contract owner to create new tokens and distribute them as needed. This can be useful for distributing tokens during an initial coin offering (ICO), rewarding users for specific actions, or creating new tokens for a platform's ecosystem.
Here are some key functions and their purposes:
- increaseAllowance: increases how much one account allows another to transfer on its behalf.
- decreaseAllowance: decreases how much one account allows the other to transfer on your behalf.
- _burn: deducts tokens from an account balance and the contract's total supply.
- mint: creates new tokens and adds them to the balance of the specified address.
Mintable and Burnable
To make a token mintable, you need to add a function to the contract that makes the built-in function _mint public, as long as the one invoking the function is the owner of the contract. This is done by adding the onlyOwner modifier, which is implemented by another OpenZeppelin library.
The onlyOwner modifier validates that the account that invoked the transaction is the same address as the variable _owner, which is the account responsible for deploying the contract. This is a simple yet effective way to control who can mint new tokens.
The OpenZeppelin library also provides a function called burn, which allows you to invoke the function _burn externally. This makes the token burnable, allowing users to burn tokens from their balance.
To make the contract burnable, you need to import the ERC20Burnable library and make the contract a child of it. This will give you access to the burn and burnFrom functions, which can be used to burn tokens from other accounts.
Here are the key benefits of making a token mintable and burnable:
- Distributing tokens during an initial coin offering (ICO)
- Rewarding users for specific actions
- Creating new tokens for a platform's ecosystem
By making a token mintable and burnable, you can create a dynamic and flexible token system that meets the needs of your users. This can be a powerful tool for building a successful token-based project.
Votes
The Votes functionality is a key part of our token's governance system. It keeps track of historical balances for voting in on-chain governance, allowing users to delegate their voting power to a trusted account.
This feature overrides three internal functions: _afterTokenTransfer, _mint, and _burn. These functions are crucial for managing token balances and transfers, and the Votes system integrates with them to provide a seamless voting experience.
The custom token contract inherits from ERC20 and ERC20Votes contracts from the OpenZeppelin library. The ERC20Votes contract is an extension of the ERC20 contract that adds support for token-based voting using the EIP-712 standard.
Total Supply
To test the total supply of a token, you can use the `token.totalSupply()` function. This function retrieves the current total supply of the token.
The `assertEq()` function is then used to compare this total supply with the constant `INITIAL_SUPPLY`. This ensures that the total supply is correct and matches the initial supply set when the token was created.
Here's a breakdown of the process:
- Purpose: To test that the total supply of the token is correct.
- Function used: `token.totalSupply()`
- Assertion method: `assertEq()`
- Constant reference: `INITIAL_SUPPLY`
Transfer and TransferFrom
The transfer and transferFrom functions in an ERC20 token are crucial for managing token balances. They are both transfer functions that decrease the sender's balance and increase the receiver's balance.
The OpenZeppelin library defines a generic built-in function called _transfer that partially implements the same logic as the transfer and transferFrom functions. This function transfers tokens from the from account to the to account without checking permissions.
The transfer function, for example, explicitly defines that the parameter from is the msg.sender. Its implementation by OpenZeppelin is straightforward.
The transferFrom function, on the other hand, checks whether the person invoking the function has permission to transfer tokens on behalf of the from account. It also changes the _allowance to discount the transferred amount.
The function _spendAllowance checks if the variable _allowance allows the transfer. It requires currentAllowance to be greater than or equal to the parameter amount. If allowed, it invokes the function _approve to change the value of the variable _allowance, decreasing the value used.
Here's a comparison of the transfer and transferFrom functions:
The transferFrom function is more complex than the transfer function, as it requires permission to transfer tokens on behalf of the from account. However, both functions are essential for managing token balances and ensuring that tokens are transferred correctly.
Check this out: Best Erc20 Tokens
Setup Function
The setup function is a crucial part of our token functionality, and it's responsible for initializing the state before every test.
This function is designed to create a new instance of the Token contract with an initial supply of 1,000,000 tokens.
Here's a breakdown of what happens in the setup function:
- Purpose: The setUp() function runs before every test to initialize the state.
- new Token(INITIAL_SUPPLY): Creates a new instance of the Token contract with an initial supply of 1,000,000 tokens.
- token.transfer(msg.sender, INITIAL_SUPPLY): Transfers the entire supply to the contract deployer's (msg.sender) address.
- vm.prank(): Simulates a function call as if it is coming from another address (in this case, msg.sender and BOB).
The setup function is a key component in ensuring that our tests are accurate and reliable.
Private State Variables
In OpenZeppelin's ERC20 contract, state variables are declared private, unlike what we did in previous lessons.
The state variable that holds the account balance is named _balances.
You must declare your own decimals function if you want to change the number of decimal places.
To override a function, you declare a function with the same name in the child contract.
In the OpenZeppelin library, the _approve function is quite simple and has not been shown yet.
By declaring private state variables, you can prevent direct changes to the original function.
To change the number of decimal places, you should declare your own decimals function, rather than changing the original function directly.
Token Deployment
You have two options to create an ERC 20 token with OpenZeppelin: start from scratch and code it yourself, or use OpenZeppelin's collection of secure and tested smart contracts as building blocks. I strongly recommend the latter, as it minimizes risk by using "battle-tested libraries" of smart contracts for Ethereum and other blockchains.
To deploy your token, you'll need to create a file within the contracts/ directory called MyToken.sol. The .sol extension signifies Solidity, the object-oriented language for implementing smart contracts.
Create a file within contracts/ called MyToken.sol, and add the following contract that inherits from OpenZeppelin's ERC20 contract.
To deploy your token, you'll need to create a Truffle configuration file called truffle.js. This file will contain the necessary configuration for deploying your contract.
Here are the main directories you'll need to create for your token deployment:
- contracts/: Directory for Solidity contracts
- migrations/: Directory for scriptable deployment files
- test/: Directory for test files for testing your application and contracts
- truffle.js: Truffle configuration file
Testing and Verification
Testing and Verification is a crucial step in ensuring the integrity of your OpenZeppelin ERC20 contract.
OpenZeppelin's ERC20 contracts are thoroughly tested and verified, with over 90% of the code covered by tests. This rigorous testing process helps catch errors and bugs early on, reducing the risk of deployment issues.
The OpenZeppelin team uses a combination of unit tests, integration tests, and property-based tests to ensure that their contracts behave as expected in different scenarios. For example, the ERC20 contract has a test that checks that the total supply of tokens does not exceed the maximum supply.
Minting Restriction Test
The MintableToken interface is used to test for minting restriction, which ensures that unauthorized users cannot mint new tokens. This is crucial for maintaining the integrity of the token contract.
The purpose of including this interface is to attempt minting in one of the test functions and ensure that users cannot mint tokens directly. It creates a way to check that the contract adheres to the standard ERC20 behavior by rejecting unauthorized minting attempts.

To test for minting restriction, the `vm.expectRevert()` function is used, which tells the test to expect a revert (i.e., a failed transaction). Since the token contract does not have a mint function, trying to mint will revert.
The `MintableToken(address(token)).mint(address(this), 1)` function is called, which attempts to interact with a mint function that doesn’t exist in the contract. This operation should fail, as expected, verifying that users can't add new tokens arbitrarily.
Here's a summary of the test:
- Purpose: To ensure that unauthorized users cannot mint new tokens.
- Function: `MintableToken(address(token)).mint(address(this), 1)`
- Expected outcome: Revert, as the token contract does not support minting.
File: Testtoken.t.sol
Let's take a closer look at the TestToken.t.sol file. This file defines a mint function that can be used to mint new tokens. However, this function is not available in the Token contract since it inherits OpenZeppelin's ERC20 standard, which doesn't include a public mint function.
The TestToken.t.sol file is likely used for testing purposes, helping developers verify the functionality of their token contracts. The fact that the mint function is not available in the Token contract suggests that it's not a standard feature of the ERC20 standard.
Contract Details
The contract details of OpenZeppelin ERC20 are straightforward and well-documented. The contract is designed to be highly customizable and flexible.
The total supply of tokens is set to a fixed number, which can be specified by the deployer. This allows for a wide range of use cases, from simple token distributions to complex economic models.
The contract also includes a mechanism for setting a new total supply, which can be useful for future-proofing and allowing for changes to the token's economic model as needed.
Pausable
The Pausable feature is a powerful tool that allows contract owners to temporarily halt the functionality of the token contract. This is particularly useful in emergency response situations.
Privileged accounts can call the pause and unpause functions to control the contract's status. These functions can only be accessed by the contract owner.
The contract's internal _beforeTokenTransfer function is overridden to ensure that transfers are only allowed when the contract is not paused. This prevents unauthorized transactions during a paused state.
Contracts

OpenZeppelin contracts provide a solid foundation for building smart contracts, and they can be easily integrated with Foundry.
To create an ERC20 contract with OpenZeppelin, you can follow the steps outlined in the code example. The key is to use the _mint function to set the total supply and balance, rather than trying to modify the internal variables directly.
Here's a step-by-step guide to creating an ERC20 contract with OpenZeppelin:
- Install OpenZeppelin contracts in your project.
- Use the _mint function to set the total supply and balance.
By following these steps, you can create a robust and reliable ERC20 contract with OpenZeppelin.
Token Interface
The Token Interface is a crucial part of OpenZeppelin ERC20 contracts, allowing users to interact with the token in a standardized way.
This interface is defined in the ERC20 standard, which specifies a set of functions that a token must implement to be considered ERC20-compliant.
The Token Interface includes functions such as `balanceOf`, `transfer`, and `approve`, which enable users to query the balance of their tokens, send tokens to other addresses, and approve third-party contracts to spend their tokens on their behalf.
Token Name and Symbol

You'll need to set the name and symbol of your token correctly. This is done by using the assertEq() function, which verifies that the token's name is "MyToken" and the symbol is "MTK".
For example, in the test section, it's shown that the token's name and symbol are correctly set by using the assertEq() function. Here's a quick rundown of the test:
- Purpose: To check that the token's name and symbol are correctly set.
- assertEq(): Verifies that the token's name is "MyToken" and the symbol is "MTK".
This ensures that your token's name and symbol are accurate and consistent throughout your application.
Mintable Token Interface
The Mintable Token Interface is a crucial part of creating a token that can be minted and managed. It serves as a way to check that the contract adheres to the standard ERC20 behavior by rejecting unauthorized minting attempts.
This interface is included in the test functions to ensure that users cannot mint tokens directly. It provides a way to interact with the token in tests.
The Mintable Token Interface includes several parameters, such as the token instance, deployer instance, bobInitialBalance, INITIAL_SUPPLY, and placeholder addresses BOB and ALICE.
Here's a summary of the parameters:
- token: An instance of the Token contract used to interact with the token in tests.
- deployer: An instance of the deployment script (Deploy) used to test the deployment process.
- bobInitialBalance: A balance of 100 ethers transferred to the BOB address as part of the tests.
- INITIAL_SUPPLY: The total supply of the token, set to 1,000,000 tokens (denoted in ethers to represent token units).
- BOB & ALICE: Placeholder addresses used for testing transfers and approvals.
Frequently Asked Questions
Can a smart contract hold ERC20 tokens?
Yes, smart contracts can hold ERC20 tokens, enforcing the token's supply and restrictions as specified by the ERC20 standard. This functionality is illustrated in the ERC20 token diagram.
Which crypto wallet support ERC20?
MetaMask is a widely used wallet that supports ERC-20 tokens, providing easy access to decentralized applications and DeFi platforms
What is the ERC20 allowance method?
The ERC20 allowance method allows token holders to control how much of their tokens can be spent by specific smart contracts or Ethereum addresses. This enables efficient resource distribution within the ERC20 ecosystem.
Sources
- https://blockchainblog.substack.com/p/how-to-create-an-erc-20-token-with
- https://medium.com/coinmonks/learn-solidity-lesson-29-openzeppelins-implementation-of-the-erc20-token-9739f7ff015a
- https://levelup.gitconnected.com/creating-erc20-token-using-openzeppelin-4272e6ec08dd
- https://dev.to/willkre/create-deploy-an-erc-20-token-in-15-minutes-truffle-openzeppelin-goerli-33lb
- https://ethereum.stackexchange.com/questions/112864/how-to-create-erc20-contract-with-openzeppelin-and-initialize-total-supply
Featured Images: pexels.com