How to build a coin and start an ICO

Let’s face it – blockchain projects and smart contracts are hot news. New coins, new ICOs are cropping up every week. So what do you need to do when you meet someone that wants to utilize this hype? I’ll give you a developer’s perspective. I’ll walk you through the process of creating a coin and the landing page using the Ethereum blockchain platform.

Our agenda:

  1. Specifications
  2. Smart contract
  3. Tools
  4. Specifications continued
  5. Implementation
  6. Deployment
  7. Testing
  8. ICO status page
  9. What if I need to change the contract?
  10. Wrapping up – the practice

So, major points first…

It all starts with a great business idea. Yes, it should definitely include creating a cryptocurrency coin having a strong and unique selling point. You need to get in cooperation with the founder to agree on a specification (which later can be used as a part of a whitepaper) and then proceed to development with thorough testing. Last but not the least, you need to create a landing page that shows the ICO status. Once your client rolls out a marketing campaign, you’re all set to go.

The specification

At laitkor, we highly value an agile approach to software development. Just as the agile manifesto tells you, we’d rather spend time developing working software than writing comprehensive documentation. However, with Ethereum smart contracts it’s just not that simple. You need to get the coding absolutely perfect from the very beginning, because as the contract goes live – it’s all final. There’s no going back. There are strategies for updating your coin or ICO code, which we’ll cover later on in the article. However, do keep in mind that every change might lower down community trust in your coin, and this can be reflected in coin price at exchanges. That’s why it’s best that you all agree on a specification which makes all the details absolutely clear to all parties.

So, what do you need to discuss with the founder?

Usually you start with an ERC20 token. You’ll need to know the token name, its symbol and whether it allows decimal fractions. And if so, how many. There’s also the decision on how many tokens can be created (total supply) and when they’re created. You can mint tokens all at once after deployment or have each ether payment create them. Consider incorporating some inflation or deflation mechanisms if it fits the idea. Other currency parameters are highly dependent on the particular business idea, so we’re not going to discuss this in depth.

With the ICO you need to consider a few basic parameters:

  • start date,
  • end date,
  • minimum and maximum caps
  • and the currency they’re expressed in.

Let’s say you want a 4 week ICO that needs to raise a minimum of 1,000 ETH and maximum of 20,000 ETH. But additionally you need to cover all the corner cases in the code – the ICO may need to end early because you run out of tokens. It’s also highly advised to add a failsafe mechanism – a possibility of halting the ICO completely in case of any security bugs or other problems. Also, customizing the ICO doesn’t end at defining its duration.

You can offer lots of other possibilities. Here are just a few ideas:

  • Tokens can be accessible instantly after a transaction or only after the ICO comes to an end.
  • The ICO can be preceded by a closed presale for invited people.
  • The ICO can also offer a bonus scheme for early buyers.
  • Raised funds may be returned if the set goal is not met.
  • Founders may get some of the initial token supply.
  • Funds raised during the ICO can be released during some vesting periods or under particular other circumstances.
  • Raised ether may be stored in the contract or transferred immediately to some other wallet (the difference is in the gas costs, accessibility of the funds and the security if you choose to store them on some particular hardware or any multisignature wallet).

Smart contract & Ethereum blockchain

Now that you’ve got the specification. Both you and the developer along with the business founder fully understand how the coin and the ICO should behave. So, what’s next?

Proceed to implementation, testing and deployment.

Unit testing the contracts is highly important as you are dealing with ample amount of people’s money. You have make sure that not even a single line of code goes untested. Test for all possible scenarios and all corner cases. Producing a bug-free product and requires an exceptional unit testing. Your attention to detail should outdo NASA! It’s a task in some ways similar to programming the Mars Rover. You wont get any chance to fix bugs once the code have gone live. Ethereum utilizes the immutable nature of blockchain and applies it to smart contracts.

Another crucial part of smart contract development are the code reviews. Each single line of code should be checked by your peers before it’s committed to the repository. Static code analysis can help discover incorrect implementation, inconsistent contract behaviour, inconsistent requirements or security issues. You can even hire security experts such as OpenZeppelin for code audit.


To showcase an example, we will develop a very basic Ethereum smart contract that represents a coin with a simple ICO. For that, we’re going to use:

Specification – continued

We’re going to use the specification mentioned before – with some added requirements:

  • REQ001: Basic ERC20 “laitkor Token” with symbol of “ESP”, 18 decimals (reflecting ether’s smallest unit – wei) and total supply of 1,000,000 units created at contract deployment and assigned to a specific wallet,
  • REQ002: The ICO is going to last 4 weeks, trying to raise a minimum of 1,000 ETH and maximum of 20,000 ETH; if the goal is not met the ICO continues until the payments reach the min cap
  • REQ003: Raised ether is going to be transferred to a specific wallet after each payment,
  • REQ004: Tokens are going to be available for transfers only after the ICO ends,
  • REQ005: The tokens are going to be sold at a flat rate of 1 ETH : 50 ESP, with added +50% bonus during the first week.


I am skipping setup and installation instructions for brevity and jumping straight to development part. Smart contracts possibly deal with huge amounts of money. So, the recommended way of starting is test-first (TDD).

Good to start small, with a test that checks whether the total supply is correct and it’s assigned to a given wallet.

const laitkorTokenIco = artifacts.require(‘./laitkorTokenIco.sol’);


contract(‘laitkorTokenIco’, accounts => {


it(‘should have initial supply of 1,000,000 units assigned to funds wallet’, async () => {
  const fundsWallet = accounts[1];
  const laitkorToken = await;


  const expectedSupply = 1000000 * Math.pow(10, 18);
  const totalSupply = await laitkorToken.totalSupply();
  assert.equal(totalSupply, expectedSupply, ‘Total supply mismatch’);
  const fundsWalletBalance = await laitkorToken.balanceOf(fundsWallet);
  assert.equal(fundsWalletBalance.toNumber(), expectedSupply, ‘Initial funds wallet balance mismatch’);

view rawlaitkorTokenIco.js hosted with by GitHub

You can see that we create an instance of our contract and check its properties by accessing the fields and calling functions.

The tests will fail at this moment and yes they should! As there is no implementation for them to test.

pragma solidity ^0.4.15;


import ‘zeppelin-solidity/contracts/token/ERC20Basic.sol’;
import ‘zeppelin-solidity/contracts/token/PausableToken.sol’;




contract laitkorTokenIco is PausableToken {
  using SafeMath for uint256;


  string public name = “laitkor Token”;
  string public symbol = “ESP”;
  uint256 public decimals = 18;


  uint256 public totalSupply = 1000000 * (10 ** decimals);


  address public fundsWallet;


  function laitkorTokenIco(address _fundsWallet) {
      fundsWallet = _fundsWallet;


      // initially assign all tokens to the fundsWallet
      balances[fundsWallet] = totalSupply;
      Transfer(0x0, fundsWallet, totalSupply);

view rawlaitkorTokenIco.sol hosted with by GitHub


We’ve got our implementation with a comprehensive suite of unit tests. Now we’re going to compile it using truffle and deploy it to the test Ethereum blockchain using (MEW). For deployment we could also use the Truffle Framework’s migrations but for the sake of simplicity let’s stick to MEW.

For easier creation of multiple token contracts with different parameters, I’ve created a Factory contract. That’s what I’m deploying.

pragma solidity ^0.4.15;


import ‘contracts/laitkorTokenIco.sol’;




contract Factory {


  function createContract(address _fundsWallet) returns(address created)
      return new laitkorTokenIco(_fundsWallet);

view rawFactory.sol hosted with by GitHub

How to deploy a smart contract?

First of all, go to MEW Contracts and make sure to select the test network node (Ropsten) in upper right corner. Secondly, click the “Deploy contract” heading, paste the contract’s bytecode compiled using truffle compile command, provide your Ethereum account, sign the transaction, click “Deploy contract” button, confirm it and you are done! After the transaction is mined the contract is live. Mine got the address 0x110FC34F504694FfE34A351B1594F84aa61D07cc.


Manual testing

The code is tested by unit tests, but you should also test your code against a working blockchain. Use the Factory contract to create token contracts with various parameters. Remember to test your contracts extensively on the test network before you go live. At that time you still can introduce bug fixes and make changes easily. Brief your client on instructions to test the contract so that they can have the first feeling on how to control it.

To create a token contract you need to interact with the Factory contract. For that, visit the same MEW Contracts page. Again, make sure you’re using the test network’s Ropsten node. Then provide the contract address and its Application Binary Interface (ABI) you got after compilation. Of course, for the Factory contract you need the Factory ABI and for laitkorTokenIco contracts created by the Factory you need the laitkorTokenIco ABI.

When you provide this data, you can already read fields and run read-only functions using the dropdown given below. For operations that need to write data to the blockchain you’re going to need to authorize yourself as well.

I’ve created a test token contract that started at 26 Jul 2017 16:00:00 GMT with min cap at 3 ETH and max cap at 5 ETH. It got deployed at 0xA292375e9343f1684e36a03b56bCe6E0664aD1f9.

Now we’ve got a working contract at the Ropsten test network which is same Proof of Work network as the main Ethereum blockchain. However, it uses Ropsten Ether. You can get it easily for free, e.g. using the MetaMask faucet. Test it until you’re sure that it works exactly according to specification. Let your client test it, get a QA specialist and do it by yourself as well.

There’s one more thing you should know about custom tokens and MEW.

To observe the balance of your coin, please add it to observed token balances under MEW Wallet Info. This is where the ERC20 standard comes in handy. That’s the interface MEW is using to read token balances.

To make it simple for this post, we’ve made a few transactions to check on how the token contract works. I’ve sent 1 ETH during the first week and got 75 ESP which is correct with the rate and bonus requirement. I’ve then sent 4.18 ETH to check if it deals correctly with decimals and whether it closes the ICO after reaching the max cap. The transfers of tokens should now be possible. So, I’ve tested this as well. These are just very simple scenarios that came to my mind. But the real testing has to be much more thorough!

After all the unit testing, code reviews and manual testing there’s still a way out to check your code for even more bugs. Deploy a fresh instance of the token contract (or publish your Factory contract ABI) and offer a bug bounty. It’s a common practice in the blockchain community, so there’s a chance some experienced developers will take a look at your code.

ICO status page

Another crucial part of the ICO is the status page. You need to inform the potential token buyers of basic ICO parameters like start and end dates, the minimum and maximum caps, the rates and bonuses etc. I’ll show you how to build a very simple ICO status page using just a Bootstrap theme, web3.js library for Ethereum blockchain integration and INFURA as a publicly accessible Ethereum blockchain node. I’m not digging deep into the design best practices or the contents. I’ll leave that up to you and the client. What I want to show you is how easy it is to display data straight from Ethereum blockchain on a website.

As you can see in the screenshot above, the website is very simple. It’s just a static HTML file with some JavaScript on top of it.

Now, let’s talk code.

<h1>laitkor Token ICO</h1>
<p id=“contractAddress”></p>
<p>Raised so far:</p>
<h2 id=“totalRaised”></h2>


<script src=></script>
<script src=“ico.js”></script>

view rawico.html hosted with by GitHub

/// utility methods
const writeValue = (elementId, value) => document.getElementById(elementId).textContent = value;
const toEthString = wei => wei / 10**18 + ‘ ETH’;


/// constants
const abi = []; // laitkorTokenIco-abi.json at
const targetApi =;
const contractAddress = ‘0xA292375e9343f1684e36a03b56bCe6E0664aD1f9’;


/// getting contract
const web3 = new Web3(new Web3.providers.HttpProvider(targetApi));
const laitkorTokenIco = web3.eth.contract(abi).at(contractAddress);


/// read and display values
writeValue(‘contractAddress’, contractAddress);
writeValue(‘totalRaised’, toEthString(laitkorTokenIco.totalRaised()));

view rawico.js hosted with by GitHub

To start small in the snippet above, we’re just displaying the total amount raised. I’ve omitted the HTML structure and styling for brevity. With some crude utility methods reading and displaying a value from a smart contract is a one-liner! Of course web3.js library offers you much more possibilities. Read the docs here.

With the rich toolset that web3.js library is offering and INFURA Ethereum nodes already in place, you can kick-off the frontend development of your ICO status page in minutes. Starting with a static HTML page with simple JavaScript that requires little-to-none infrastructure you can go further. Add cool progress bars, pretty designs, with some backend work a user registration page and more.

What if you need to change the contract?

The token is live and the ICO is in progress. However, you’ve noticed a serious bug and you need to fix it ASAP. I’ve said before that once you deploy it the smart contract’s code is final and it can’t be changed. Yes, that’s true but fortunately there is a way to update your token – even after it goes live. Be aware that you’re changing a contract that people may have already agreed upon. It’s not a decision to be made lightly!

There are two popular strategies to updating contracts. Here’s the first one one.

It’s essentially uploading a new one and informing people about it. But there’s a little more to it. The process starts in a similar way as it did before. Agree with your client on the bugfix scope or any other requirements, change the code and unit tests and test the contract again. The next thing is to plan a data migration from the previous contract if you haven’t planned to store your data in a separate contract.

There are many ways to do it.

Let’s say you want to migrate token balances from the bugged contract. The easiest way to do it is to prepare a smart contract that will call the standard ERC20 balanceOf() function to read token balance for a particular address. Then, assign the token balance to the new contract. When you’ve got both the fixed token and the migration contracts ready and tested you can proceed to deployment.

Firstly, publish informative community announcements explaining what, when and why you’re going to change with the token contract. Then, use the failsafe mechanisms in your contract. Halt the fundraising and pause all token transfers so that the contract is frozen and no token balances can change. Get the list of token buyers for the data migration, e.g. from and deploy it. Update the smart contract address on all your pages and you’re done.

There’s also another way.

You can organize your contracts in an object-oriented-like structure, where the main contract with publicly announced address is a Proxy which refers to other contracts for the actual work execution. This is how you plan for modifiability in your Ethereum blockchain code. However, having that modifiable Proxy lowers the trustworthiness of the contract because the owner can change the work delegates at any moment. This is a delicate balance between blockchain’s trustlessness and systems that require one to trust the owner. Having said all that, ERC20 tokens are rather simple contracts, so they should not use the Proxy pattern.

As you can see, updating an Ethereum smart contract is not that easy. You need to either prepare the community for the change and perform data migration, or plan any contract modifications upfront. That’s why developing contracts is hard, especially if you try to get the contract 100% right from the start.

Wrapping up

With this article, I’ve attempted to introduce you to the world of Ethereum smart contracts and ICOs. We started from the importance of a good specification, went through the development of smart contracts, putting extra stress on automated and manual testing. Then we found how easy it is to build a simple ICO status page and finished with the hardships of introducing changes to your smart contracts.

Now you know how to build the token contract, get the ICO status page up and running successfully. So you’ve got the development part pretty well covered. There’s more to a successful ICO. May be you need a white paper describing the business idea, technical execution and a marketing strategy to reach potential buyers. But that’s a different story, can be covered in another article.

The practice

ICOs and smart contracts are what we’re working on at laitkor. In August, we’re also holding developer workshops on how to build tokens and ICOs with Ethereum smart contracts. With all that expertise we can offcourse share insights like this article with you.

Leave a Reply