ICO Smart Contracts – Part 2

September 13, 2018

Author: Akarsh Agarwal

Tutorial - MLG Blockchain

Now, that we have looked at the declaration of our unique token on the Ethereum Blockchain using Smart Contracts in part 1 of this series on how to deploy an ico crowdsale smart contract (SC). Now, let’s move our focus towards the crowdsale smart contract, where we use the token SC to transfer some real tokens to the buyer. We are using the Open-Zeppelin’s security standard out of the box and greatly appreciate the great work they do contributing to the blockchain development community.

So, let’s get started with it!

Explaining the Variables Declared

While in previous article, we saw that we didn’t have many variables to declare and initialize, as there was no requirement for the same. But, when it comes to Crowd Sale, we need to maintain the duration, beneficiary, total raised amount, max-min cap, etc.

So, let’s first look at the code snippet below and following is the explanation of each variable:

Token public token;
address public beneficiary;
uint256 public tokenPerEthPreSale;
uint256 public tokenPerEthICO;
uint256 public presaleStartTimestamp;
uint256 public presaleEndTimestamp
; uint256 public icoStartTimestamp;
uint256 public icoEndTimestamp;
uint256 public presaleTokenLimit;
uint256 public icoTokenLimit;
uint256 public presaleTokenRaised;
uint256 public icoTokenRaised;
uint256 public presaleMaxEthCap;
uint256 public icoMinEthCap;
uint256 public icoMaxEthCap;
uint256 public investorCount;

We have quite a lot of variables here, so let’s get started:

  • token: It defines the token contract you deployed for your unique token and requires its address.
  • beneficiary: The final account where the funds will be transferred from the contract, after the ICO concludes.
  • tokenPerEthPreSale, tokenPerEthICO: As the name suggests, it is the number of tokens per Ether during the Pre-Sale and ICO period, respectively. This will encourage investors to buy tokens at Pre-Sale stage, because this will help them buy more token per Ether.
  • presaleStartTimestamp, presaleEndTimestamp: These variables define when the Pre-Sale starts and Ends. This makes sure the Pre-Sale is bounded within time limits and doesn’t run forever.
  • icoStartTimestamp, icoEndTimestamp: Similar to above, but for the ICO Sale, which takes place after Pre-Sale.
  • presaleTokenLimit, icoTokenLimit: Generally not all tokens are available for Sale during the ICO. So, a fixed amount of tokens are sold only during the Pre-Sale and the rest is sold during ICO Sale.
  • presaleTokenRaised, icoTokenRaised: This keeps track of total amount of Ethers raised during the Pre-Sale and ICO, respectively.
  • presaleMaxEthCap, icoMaxEthCap: This is to stop the Crowd Sale, when we reach our desired funding amount.
  • icoMinEthCap: If the project plans on raising a minimum amount in the Crowd Sale, this is set with the minimum required Ethers, for a successful ICO.
  • investorCount: This keeps track of how many unique people have purchased your token. The higher the number of investors, the more distributed it is and no single person owns the authority.

This is a brief about most of the variables declared. You can find more information on the SC itself, on Github.

Now, how do we make ensure, which state the ICO is in, whether, Pre-Sale, ICO Sale, or Concluded? For this, we can use “enum” to keep track of the current state of the ICO Sale. Below is a code snippet for the same:

enum State{Unknown, Preparing, PreSale, ICO, Success, Failure, PreSaleFinalized, ICOFinalized}

Following is brief about all the states:

  • Unknown: It is the default entry level state. This means that nothing has been received and the contract has now been deployed.
  • Preparing: When we are initializing the variables, mainly in the constructor, we use this state.
  • PreSale: As soon as the current Timestamp crosses the Pre-Sale’s Start Timestamp and transaction are incoming, the state changes to “PreSale” as it is in the Pre-Sale phase of the ICO.
  • ICO: Similar to above, but only applicable for ICO’s Sale Start Timestamp.
  • Success: If the ICO is successfully able to raise enough to cross the minimum cap, we set the state to Success and transfer the funds to the beneficiary.
  • Failure: When we fail to raise more than the minimum cap, all the investors are liable to a refund of the money they have already put in.
  • PreSaleFinalized: The state when the ICO is between Pre-Sale Period and ICO Sale Period.
  • ICOFinalized: The state is after the ICO has been concluded but funds have not been transferred to the beneficiary.

Now, that we have learnt about all the variables, let’s move to initializing and learning some of the functions to ensure smooth operability and secure usage.

function TokenSale(
address _token,
uint256 _presaleRate,
uint256 _icoRate,
uint256 _presaleStartTime,
uint256 _presaleDays,
uint256 _icoStartTime,
uint256 _icoDays,
uint256 _maxPreSaleEthCap,
uint256 _minICOEthCap,
uint256 _maxICOEthCap) { }

This is used to initialize all the above mentioned variables with passing parameters to the constructor. This makes sure that as soon as the contract is deployed, we have the required values in place and transactions can happen according the start/end timestamps.

Although most of the arguments are self explanatory, some of the arguments need an explanation.

_presaleDays, _icoDays: It specifies the time the Pre-Sale and ICO Sale is to be run. This is added to the start timestamp respectively and hence, end timestamps are calculated.

Now, that we have initialized the variables, let’s move to our next function which is to calculate the amount of tokens. The structure is:

function calculateTokens(uint256 _amount) returns (uint256 tokens) { }

This function helps in calculating the number of tokens according to the ethers transferred. Also, it takes into account the different selling price for tokens during Pre-Sale/ICO.

Another important part of the ICOs are statistics. While the ICO is running, people like to have real-time statistics on the website to make them believe about the tokens sold and number of investors. This acts as a medium of trust and motivation for them to buy, seeing so many investors worldwide. Here is a code snippet of some very basic statistics functions.

function getInvestorCount() constant returns (uint256) { }
function getPresaleRaisedAmount() constant returns (uint256) { }
function getICORaisedAmount() constant returns (uint256) { }

Here we have 3 functions:

  • getInvestorCount(): This displays the number of different investors who have bought the tokens. This assured the buyers that a large number of tokens are not owned by a handful of investors and that the ownership is distributed.
  • getPresaleRaisedAmount(), getICORaisedAmount(): This will display the total money raised in Pre-Sale and ICO, respectively. This lets investors know about the success of the vision of the token, the company is trying to sell. Also, it helps the team know whether they are going to raise the specified amount or not.

While, I have taken only some of the functions, stay tuned for our next article, which will cover other functions in detail and finally conclude our tutorial of teaching you about writing a simple token sale smart contract for an initial coin offering.

About MLG Blockchain

MLG Blockchain is a global blockchain consulting and development firm headquartered in Toronto with a distributed team across North America, Europe and Asia that is focused on building next generation applications using blockchain and smart contract technology. We speed up your team’s understanding of the blockchain and its potential opportunities for your business and help you to create a blockchain strategy you can use today.

If you are part of the executive team of a new or existing token, please reach out at hello@mlgblockchain.com to be profiled.