Creating Upgradeable ERC20 Tokens
As you know one of the most popular Ethereum tokens is ERC20. But what is ERC20?
The ERC-20 Ethereum token standard is a blueprint for creating fungible tokens that are compatible with the broader Ethereum network. The most important feature of ERC20 is that tokens are fungible. This means that each token is equal to all the other tokens like BNB, USDT. (For other ERC20 tokens https://etherscan.io/tokens)
Smart Contracts in Ethereum are immutable by default. If we want to make changes on our contract in the future, we may want to use Upgradeable Contract feature. There are many advantages of making the contract upgradeable instead of deploying a new contract. As we create and deploy a new contract, the contract address will change. So you will need to update all contracts that interacted with the old contract to use the address of the new version. You will also have to reach out to all of your users and convince them to start using the new contract and handle both contracts being used simultaneously, as users are slow to migrate.
We can use a proxy contract with an interface where each method delegates to the implementation contract.
The first contract is a simple wrapper or “proxy” which users interact with directly and is in charge of forwarding transactions to and from the second contract, which contains the logic. The key concept to understand is that the logic contract can be replaced while the proxy, or the access point is never changed. Both contracts are still immutable in the sense that their code cannot be changed, but the logic contract can simply be swapped by another contract. The wrapper can thus point to a different logic implementation and in doing so, the software is “upgraded”.
Whenever you deploy a new contract using deployProxy in the OpenZeppelin Upgrades Plugins, that contract instance can be upgraded later. By default, only the address that originally deployed the contract has the rights to upgrade it.
Okay, now hands-on!
1. Create a project
You can create a new project name and location by typing the following command in your computer’s CLI.
$ mkdir <YOUR-PROJECT-NAME> && cd <YOUR-PROJECT-NAME>
2. Installations
Firstly, if you don’t have truffle installed, download it from here.
We’ll be using local network in this example so we will need Ganache. You can use these commands to run Ganache.
$ npm install — save-dev ganache-cli && npx ganache-cli — deterministic
After this step, open a new terminal page.
To get started with Truffle we will install it in our project directory.
$ npm install — save-dev truffle
Lastly, install the Truffle Upgrades plugin.
$ npm install --save-dev @openzeppelin/truffle-upgrades
3. Create “truffle-config.js” file
(Path =>”YOUR-PROJECT-NAME”/truffle-config.js)
We are going to use this file to configure our truffle project.
module.exports = {networks: {development: {protocol: 'http',host: 'localhost',port: 7545,gas: 5000000,gasPrice: 5e9,network_id: '*',}}};
4. Next step: Contracts
For this example, we will have 2 contracts. One of them will be the master contract called “UpgradeableERC20” and then we will upgrade it.
Create a new folder named “contracts”, add UpgradeableERC20.sol file inside of it and copy&file the code below. This is a simple ERC20 token on which we will apply changes.
contracts/UpgradeableERC20.sol
https://gist.github.com/SeherSaylik/0ef8b9e0220f8f8c2d5c41f80d102083
The point that we need to be careful about is using initializer function instead of constructor. Normally constructor is used in standard ERC20 token structure but upgradeable contracts don’t allow us to use it.
Add NewERC20.sol file to ‘contracts’ folder.
contracts/NewERC20.sol
https://gist.github.com/SeherSaylik/0ef8b9e0220f8f8c2d5c41f80d102083
In this section we added transferFrom function below to the current contract.
5. Migrations
Create a folder named ‘migrations’ and the following migration files.
migrations/1_initial_migration.js
const { deployProxy } = require(‘@openzeppelin/truffle-upgrades’);const UpgradeableERC20 = artifacts.require(‘UpgradeableERC20’);module.exports = async function (deployer) {await deployProxy(UpgradeableERC20, [‘YOUR-TOKEN-NAME’,’YOUR- TOKEN-SYMBOL’,’YOUR-DECIMAL',’YOUR-SUPPLY'], { deployer, initializer: ‘initialize’ });
};
migrations/2_upgrade_proxy.js
const { upgradeProxy } = require('@openzeppelin/truffle-upgrades');const UpgradeableERC20 = artifacts.require('UpgradeableERC20');const NewERC20 = artifacts.require('NewERC20');module.exports = async function (deployer) { const existing = await UpgradeableERC20.deployed(); await upgradeProxy(existing.address, NewERC20, { deployer});};
6. Deployment
We are ready to deploy!
Preparation: DON’T FORGET TO KEEP GANACHE OPEN
Ganache allows you to create a private Ethereum blockchain for you to run tests, execute commands, and inspect state while controlling how the chain operates. It gives you the ability to perform all actions you would do on the main chain without the cost.
Make sure that the numbers 1 and 2 at the beginning of the migration file names are written in order for the commands to work.
First, we will run the first migration to deploy UpgradeableERC20.sol file. The command you need to type in your terminal:
$ npx truffle migrate --to 1 --network development
Perfect! We deployed our contract to the local network with 0.010150925 ETH cost. Now it’s time to update the contract with the added transferFrom () function.
The command to run the 2nd migration only:
$ npx truffle migrate --f 2 --to 2 --network development
As you can see, it replaced the contract with NewERC20 and cost less ether than the previous distribution cost.
Another important detail in such contracts is that when we update our contract, previous transactions are kept and continued. For example, let’s send a token to an address with the UppgradeableERC20 contract with the help of the truffle console. Then let’s update the contract with NewERC20. You will see that the token we send to the address will remain even if we update the contract.
Command:
$ truffle console
If you do not want to deal with the editing steps, you can download the full project from the Github link below and modify it according to your project.
If you want to work on blockchain and read my blog posts, you can access Archi’s Academy web page here.