Create a Crowdsale for an ERC-20 Standard Token Using Truffle, and Deploy With Infura

A hands-on web3 development tutorial

Samuel Okafor
Better Programming

--

Photo by Shubham Dhage on Unsplash

The Metaverse has been a huge buzzword in recent times. It is not a no-brainer that its peak in popularity coincided with the Facebook name change and the company’s public intentions of doing great exploits in the space.

Not to be outdone by their fellow tech giant, Microsoft also made public of its desire to make immediate strides in the Metaverse. From all we have seen, it is quite obvious that we are in the early stages of a multi-billion race between the big tech firms to gain a strong foothold in the next big thing.

Alongside the Metaverse, NFT is another trending topic that has managed to capture the curiosity of most people. Several cases of celebrities taking out their personal pictures on their social media profiles and replacing them with pictures of apes have gone a long way in creating awareness for this phenomenon which is an abbreviation for “Non Fungible Tokens”.

The already stirred interest is only further escalated when one discovers how much it cost to own the pictures of the Apes. The buzz around NFTs makes for a very curious discussion but staying true to the title of this article I will be taking us through the creating of a crowd-sale for an ERC-20 standard token for now.

What is a crowd sale?

A crowd sale is a public offering and sale of a relatively new cryptocurrency or digital asset.

So, we can rephrase it as early offerings to the public with the promise of making them initial owners of the cryptocurrency or asset.

ERC-20 standard tokens are fungible tokens built using the ERC-20 smart contracts. They account for the majority of the altcoins in existence. Like I mentioned earlier, they are fungible tokens which are in contrast to the buzzing NFTs that are renowned for being non-fungible.

The major difference between the two asides that fact that they use two different ERC standards is the fact that fungible tokens are interchangeable and can be exchanged, unlike their non-fungible counterparts.

The very first step I took to start this project was installing truffle globally on my system using the NPM command.

I needed a Truffle box with a pre-existing frontend so I decided to go with the Truffle React box. This choice was influenced by my past experience creating client-side codes with the JavaScript framework.

There are some differences between ReactJs on Web2 and on Web3 but its structure and foundations are still the same. One feature that sets apart the Web3 version of ReactJs writing is the need to be able to call smart contracts and their in-built functions.

npm install truffle -gnpx truffle unbox react

A correctly unboxed Truffle React box should automatically set up the directories as shown below

The truffle-config.js is an important file that contains the necessary configurations that enable the compilation and deployment of smart contracts.

We specify the exact solidity version that would be used in the compilation of our smart contracts and also the details of the Ethereum network that we are trying to connect to.

As we are all aware, deploying smart contracts cost real money, so it is very important that tests are done on the Ethereum testnets or on a private ethereum node.

Therefore we can ensure that we have made every necessary adjustment before deploying to the mainnet which requires real money to cover the gas fees. Attached below is a sample of what our truffle-config.js is meant to look like:

As I mentioned earlier, we will be creating ERC-20 tokens for our crowd sale project. ERC is an abbreviation for ETHEREUM REQUESTING FOR COMMENTS.

Creating ERC-20 tokens from scratch can be an exhausting and complicated task and we owe it to the good people at Openzeppelin that provides ERC standard smart contracts we can work with because they make our work a whole lot easier.

These smart contracts are regularly updated and improved to ensure their capabilities are up to date. All we have to do is import the ERC contract we want into our project directory and we can start creating our ERC-20 token.

npm install @openzeppelin/contracts

Older versions of the Openzeppelin smart contracts have the crowd sale smart contract but over time, this solidity file has been phased out. The use of this contract gives us the luxury of focusing more on some extra logic behind the crowd sale knowing fully well that the Crowdsale smart contract has us covered.

Therefore to take advantage of the availability of pre-existing Crowdsale smart contracts, we will have to make use of an older version of the Openzeppelin contract.

To install specific versions of an npm package, we just add the version at the end of the install command.

npm install @openzeppelin/contracts@2.5.0

The unboxed truffle react box comes with pre-existing files in the contract and test folders.

These files are not related to our project, so it is advised that they be deleted.

We will need to create our token contract that will interact with the already imported Openzeppelin contract to create our ERC-20 token.

Above is a template from Openzeppelin for creating our token contract that interacts and inherits the already imported ERC20 standard contracts.

In solidity, we can access functions of external contracts using inheritance. We do this using the “is” keyword. Therefore, we can modify the above contract to create our token. We can add our preferred token name, its symbol, and the total number of tokens available at its inception.

One noticeable difference between my final token contract code and the original template provided by Openzeppelin is the version of solidity that I used.

This is necessary because having access to the Crowdsale contract means that I had to use an older version of Openzeppelin. It is necessary to ensure that all the files are running on the same version of solidity.

As I mentioned earlier, we specified a version of solidity in our truffle-config.js file, therefore it is paramount that every solidity file in our project is running on the same version. This is an error that a lot of people encounter when building their decentralized projects.

The Crowdsale.sol file alone doesn’t have everything required to enable our token sale, so to complete this it is required that we create another file to define the logic and enforce more conditions regarding purchasing tokens.

The beauty of smart contracts is how it provides an avenue for developers and creators to set and enforce rules that can’t be tampered with. A great example of a rule that I got to enforce working on this project is a demand that every purchaser of the ERC-20 token has to go through a verification process of some sort.

To do this, I wrote a KYC smart contract that ensured that only addresses that have passed the verification process can partake in the crowd sale for my token.

In the KycContract, we inherit the Ownable contract. The Ownable contract is provided by Openzeppelin and it contains functions that ensure that only the owner of the contract can call desired contracts. These functions are known as modifiers and their duty is to ensure that certain conditions are met before some functions are executed. When we are done with the KycContract, we can move forward to importing it to our TokenSale contract to ensure that the KYC conditions are met before a token purchase can be executed.

At this point, we are done with our smart contracts, and we have to move to the next junction which is ensuring that our migration files are perfectly set up.

On observation, you would find a Migrations sub-folder, and this houses two files: 1_initial_migration.js and 2_deploy_contracts.js. We do not get to make alterations to the first as it comes automatically set but we have to make changes to the latter to accommodate our solidity files and make sure that the contracts are deployed in the correct way.

After we are done with the migration files, our next stop is a very important one. The concept of Web3 transactions charging real money for gas is not new, so it is very important that the codes that we write are carefully verified and inspected before we push them onto the mainnet.

To ensure the efficiency and accuracy of our smart contracts, we write unit tests to make sure they work as they should under certain conditions. Testing on solidity is also done using some popular Test libraries like Chai, Mocha.

npm install chai chai-as-promised chai-bn

We have to write tests for our ERC-20 token smart contract and our token sale contract. This is to ensure that they are both working in the manner expected before we can deploy to the Ethereum network. Then we run the truffle test in the terminal.

Our tests run successfully, therefore it is time to cross over and make the required adjustments to our React codes for our frontend.

The Truffle React Box comes along with pre-existing React codes that we have to alter to be able to connect with our smart contracts in order to have a functional decentralized application.

Before I go any further, it is important that I highlight that after our smart contracts are successfully compiled and migrated, they are stored as artifacts on the client-side of our projects.

So instead of importing the contracts directly into our ReactJs files, we rather import the artifacts. These artifacts contain the contract ABI which enables us to access the contract functions in our React files. ABI is an acronym for Application Binary Interface.

We are set to deploy our decentralized app to the ethereum main net and like the whole blockchain ecosystem, that comes with some hurdles of its own.

However, a standout feature of the ecosystem is a huge plethora of apps or software at our disposal aimed at making every step relatively easy. The subject of deploying is where Infura comes in.

What is Infura? Quoting the creators, “Infura provides the tools and infrastructure that allow developers to easily take their blockchain application from testing to scaled deployment — with simple, reliable access to Ethereum and IPFS.

To get started with Infura, it is required that we create an account. When we are done registering, we are then redirected to the dashboard where we can create a new project.

Ethereum is selected as our product type because we are creating an Ethereum product. ETH2 is another option on the dropdown but it is currently still in its early stages.

ETH2 is an upgrade to the current version of the Ethereum blockchain that is aimed to battle the biggest issue plaguing the platform which is the crazy gas fees. It will also mark the transition from the Proof Of Work(POW) to the Proof of Stake(POS) consensus mechanism.

After we have created a new project, we will be given a unique Project ID and Project Key that is required for making connections to the Infura endpoints. Infura gives us the option of making our choice of endpoint, it could be the mainnet or the testnets.

The most renowned testnets are available and they are Ropsten, Goerli, Kovan, and Rinkeby. As I have mentioned several times, deploying to the Mainnnet costs real cash, so it won’t hurt to deploy to the Testnet to ensure the smooth running of our project before deploying to the mainnet.

To deploy on the testnet, we will be needing testnet tokens instead of ether, and we can easily get these from faucet sites for no charge. Below are faucet websites for the Testnets.

Ropsten: https://faucet.ropsten.be/
Goerli: https://goerli-faucet.slock.it/
Rinkeby: https://faucet.rinkeby.io/

With the Project ID and Key provided by Infura, we head back to our truffle-config.js file where we can make a few modifications that will enable the project to connect to our preferred Infura endpoint.

That’s it!!

At this point, we have done everything necessary to deploy our project to the Ethereum blockchain.

It is a fulfilling feeling, getting to deploy a contract and interacting with the blockchain knowing that you are very early to a technology that is going to change the whole world.

We have barely scratched the surface with regards to Blockchain/Web, and it is amazing what has been achieved already. Most tokens out there, both fungible and non-fungible were created using the same standards and steps that we have gone through, and when we take into consideration the impact that they have had then we can realize the opportunity that we have been given on a platter to make an impact on the world with just a couple line of codes.

For a look at the complete codebase for my project, here is the link to its Github repository.

--

--