Developing Smart Contracts: ERC20 Token

Seungwon Go
Dec 17, 2018 · 13 min read

By Seungwon Go, CEO & Founder at ReturnValues (seungwon.go@returnvalues.com)

Truffle Framework(https://truffleframework.com/) is a framework, which enables you to develop, test and build Smart Contract in Solidity fast and easily.

One of the best things about using Truffle is that you can write and run test cases for various scenarios in your local environment without deploying to Testnet or Mainnet. Had it not for a framework like Truffle, in order to test the smart contract you developed, you would have to develop a DApp and run every test case through Metamask. It would take a lot of effort and you would need to do it continuously and repeatedly, until you finish with the development.

Now, let’s configure the development environment.

Configuring the Environment for Developing Smart Contracts

I assume that you already have Node.js installed. If not, you need to install one (https://nodejs.org/en/) of a version appropriate for your OS.

Now, open up the terminal and enter the command below to install Truffle.

npm install -g truffle

Then, create a project folder for developing a new smart contract. You can create one where you want. I’ve created one with the name truffle-demo.

Move to the folder you created and run the command below in the terminal:

truffle init

After running the command above, new folders and files will be automatically generated inside the project folder.

Here are short explanations on the folders and files generated by the command truffle init.

  • contracts(folder) : here, smart contract files developed in solidity are stored in this folder.
  • Migrations.sol(file) : this file is solidity file, which is for deploying smart contract program. You should not delete this file.
  • migrations(folder) : here will be script files that are for deploying. Everytime you develop a smart contract program, you will make a corresponding migration file in this folder and the script files are ordered.
  • 1_initial_migration.js(file) : it is a script file for deploying Migrations.sol.
  • test(folder) : it is a folder to test smart contract programs developed. In this folder, you write test cases and run them with the command ‘truffle test’.
  • truffle.js(file) : it is a configuration file for Truffle. Here You can set information such as host, port, networkID etc. for development.
  • truffle-config.js(file) : it is also a configuration file for Truffle. This is used as config file in case truffle.js file doesn’t exist.

Before developing ERC20 token, let me briefly explain what ERC20 is.

In Ethereum, when a programmer wants to propose a standard, he/she submits EIP (Ethereum Improvement Proposal). When it gets approved, it becomes ERC(Ethereum Request for Comments). And the number 20 is a number to identify the proposal document.

There are also other ERCs for creating tokens, other than ERC20. But most of the tokens you’re familiar with such as EOS, Filecoin, Bancor, Qash, Bankes are based on ERC20. In case of EOS, though, is no more on Ethererum but on its own blockchain platform.

Most of the tokens that are being used for recent ICOs are based on ERC20. So we can say ERC20 functions as a standard for creating a token.

Now, let’s get started with developing a ERC20-based token smart contract. Fortunately, openzeppelin, an opensource project, provides a basic smart contract for creating tokens and crowdsale. And you can develope a token with the features you want very easily.

First, type the command below to install openzeppelin:

npm install openzeppelin-solidity --save

You can see the openzeppelin-solidity folder was generated under the node_modules folder.

Developing Smart Contracts: ERC20 Token

I’ll use Visual Studio Code as an editor. Create a file named “SampleToken.sol” in a contracts folder.

And copy the code below and past it into that file.

pragma solidity ^0.4.24;

pragam solidity ^0.4.24; in the first line indicates the version of solidity compiler. Since solidity is being continuously upgraded and each version provides different codes, so you need to specify which version you use for developing so that your program will be compiled with the solidity of the version you specified when it’ll be run.

We’ve already installed openzeppelin. We’ll inherit from one of the solidity programs that are already developed in the openzeppelin-solidity / contracts / token / ERC20 folder.

Now, let’s have a look at the solidity program we’ll inherit from inside the ERC20 folder.

Open DetailedERC20.sol file in your editor.

ERC20Detailed

ERC20Detailed.sol inherits from IERC20 and you can declare token name, token symbol, token decimals for this smart contract. This means that you can make a new token with the name, symbol and decimals you want.

Here, you need to clearly understand what the variable ‘decimals’ means. decimals refers to how divisible a token can be, from 0 to 18 and higher. The decimals value is the number of digits that come after the decimal place when displaying token values on-screen. Ethereum does not deal with decimal numbers, so you need to represent all numeric values as integers. In order to understand the total supply, you need to have a clear understanding about the decimals.

For example, if you’ve decleared total supply of the token as 100,000 and set the decimals as 3, the real token amount will be 100.000 which is 100, not 100,000.

Now let’s inherit from ERC20Detailed contract, and define a new token you want to generate.

pragma solidity ^0.4.24;

When our new token contract is generated, you’ll deploy it to Ethereum testnet or mainnet and you’ll declare variables as parameters for generating a contract.

You declare variables that are need for generating tokens when creating contracts.

In case of ERC20.sol that you inherited from, only interface was declared. In order to complete, you need to inherit from another contract.

Open ERC20.sol in the openzeppelin-solidity / contracts / token / ERC20 folder, you’ll find the code that implements the interface declared in ERC20.

Now let’s change our code so that it inherits from ERC20.sol.

컨트랙트 생성시 토큰 생성을 위해 필요한 변수를 선업합니다

In case of ERC20.sol that you inherited from, only interface was declared. In order to complete, you need to inherit from another contract.

Open ERC20.sol in the openzeppelin-solidity / contracts / token / ERC20 folder, you’ll find the code that implements the interface declared in ERC20.

Now let’s change our code so that it inherits from ERC20.sol.

pragma solidity ^0.4.24;

Now you have created a token with basic features by inheriting from ERC20Detailed and ERC20. You’ll add several features from now on, but before that, let’s test the developed program and deploy it.

Compiling Smart Contracts

Now, let’s compile the program that we developed so far.

Run the command below in the terminal:

truffle compile

If there’s no error in the program, you’ll get the messages as follows:

In the compiling process, all the files that are imported in the program, get found and compiled. When it’s done with compiling, the build folder will be generated in the project folder and json files that are correspondent with the compiled Solidity files will be generated in the build folder as shown below:

Generating Migration Files

Create a file with the name 2_contract_migration.js and copy the code below into that file.

var SampleToken = artifacts.require("./SampleToken.sol");

Writing Test Cases

Before deploying to testnet, let’s write and run test cases to test if the smart contract we made work properly.

Fortunately open-zeppelin provides various features that are needed when writing test cases and we’re going to use them. In the link below, down the helpers folder and save it in your project folder.

Now, create a new file named SampleToken.test.js in the test folder, and copy the code below and past it into that file.

const { expectThrow } = require("../helpers/expectThrow");

The test code above is meant to test 8 cases:

1. to check if the token name is the same as the name set in the variable.

2. to check if the token symbol is the same as the symbol set in the variable.

3. to check if the decimals is the same as the decimal set in the variable.

4. to check if the total supply is the same as the total amount set in the variable.

5. to check if all the tokens issued were transferred to the address of the token creator.

6. to check if the token owner can transfer as much as he/she wants to a specific address.

7. to check if the revert feature works properly when the token owner tries to transfer more tokens than he/she has left.

Configuring the Environment for Testing and Deploying

In your project folder, you’ll find truffle.js and truffle-config.js. Open truffle.js file and edit it as below:

module.exports = {

Then, in order to use an account for testing in your local environment, install Ganache. You can download it from https://truffleframework.com/ganache.

After running Ganache,click the settings icon on the top right, which will move you to the settings. Set the port number 7545, as set in the truffle.js.

Now, we’re ready for testing. In the terminal, write the command below, which will run the smart contract you wrote previously.

truffle test ./test/SampleToken.test.js

You’ll get an error message as below in the terminal:

In order to test, you need web3 module. Other than that, you need several other modules in order to use several functions in the helpers folder that you copied and pasted to write test cases.

You can install all the needed modules by running the commands below:

npm i web3 --save
npm i chai --save
npm i chai-bignumber --save

Now, let’s run the test again.

truffle test ./test/SampleToken.test.js

The test goes through the written test cases, and the test results will show in the terminal as below:

Now, you can see all the 8 test cases were run successfully.

Deploying to Testnet

In order to deploy to testnet or mainnet, open the truffle.js file and edit it so that it looks as follows:

require("dotenv").config();

In order to use dotenv and truffle-hdwallet-provider-privkey, you need to install the modules below in the given order. The commands are:

npm i dotenv --save
npm i truffle-hdwallet-provider-privkey --save

dotenv is a module with which enables you to save key values and load them while running the program.

Before deploying smart contracts to testnet, you need to create an account for the contract owner at https://www.myetherwallet.com. Also you need to create INFURA API KEY at https://infura.io with the account you’ve created.

On this topic, you’ll find many articles in the Internet.

Now, create an .env file in your project root folder. Open it and add the two lines below and write down the PRIVATEKEY and INFURA_API_KEY of the account you’ve created

PRIVATEKEY=

Then, let’s deploy the contract to testnet.

I chose ropsten as the testnet to deploy to, and the command to deploy is as below:

truffle migrate --reset --network ropsten

If the contract has been successfully deployed, you’ll get a message as below:

Now, go to the website https://ropsten.etherscan.io/ and search with token contract address. You’ll see that the token was created successfully.

Verifying and Publishing Smart Contract

Open the Code tap and click “Verify and Publish”, and you’ll see the screen where you can verify code of the deployed smart contract.

In order to verify the deployed smart contract, you need all the code of the modules that were imported in your program.

The truffle-flattener module takes all the files and their dependencies and puts them into one new file.

Use the command below to install truffle-flattener.

npm i truffle-flattener --save

When it’s done with the installation, let’s make a file that includes all the code that are being referenced using truffle-flattener.

First, create a folder named flat in your project root.

Run the command below in the terminal:

truffle-flattener ./contracts/SampleToken.sol > ./flat/SampleToken_flat.sol

When you run the command, it takes all the contract code, from not only the contracts that are imported but also what the imported contract files are referencing, and concatenate them and put them into the SampleToken_flat.sol file in flat folder.

Now, open SampleToken_flat.sol file, copy all the code in it, and paste them into the editor in the Code/Verify and Publish tap of the deployed SampleToken contract in https://ropsten.etherscan.io.

Choose SampleToken for Contract Name, and choose Compiler of your chosen version. Choose No for Optimization and click Verify and Publish button.

If the contract gets verified successfully, you’ll see the screen as follows:

If you click ‘Successfully generated ByteCode and ABI for Contract Address’ button, you’ll see the SampleToken that you deployed. Unlike before you verified the code, in the Code tap, you’ll see all the contract code that you generated using truffle-flattener. Also the tabs such as Read Contract and Write Contract will be activated.

If you click Read Contract tap, you’ll see the token generation information as follows:

If you click Write Contract tap, you can directly execute functions that are provided by the token contract that you developed.

Hoorey! you have successfully implemented ERC20 based token and deployed it to testnet. The steps to deploy to mainnet is the same.

Open the truffle.js file and set the information as below and choose mainnet when you type command migrate. Then the contract will be deployed to mainnet.

require("dotenv").config();

Extending ERC20 Token Features

Now, let’s add some feature to our token by inheriting from MintableToken, PausableToken and Burnable Token.

•MintableToken: this token type means that you can mint token after your initial token generation.

•PausableToken: If your token is PausableToken, you can choose to Pause in a certain circumstance in order to pause features such as transfer and approval.

•BurnableToken: If your token is BurnableToken, you can irreversibly destroy some amount of tokens.

pragma solidity ^0.4.24;

Now, try to deploy smart contract that include additional features, by going through the steps to test and deploy.

So far, we have easily generated our own token based on ERC20 using open source project openzeppelin. The token we generated is a contract with the most basic features. In order to develop more advanced token contract, I recommend you to analyze the contract code in openzeppelin.

ReturnValues

ReturnValues Blogs

Seungwon Go

Written by

Founder & CEO at ReturnValues

ReturnValues

ReturnValues Blogs

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade