Update: I'm writing a book on Ethereum Smart Contracts. It's available for purchase on LeanPub. If you are interested in learning more about Smart Contracts and building Decentralized apps, feel free to give this a try.

If you are looking for advanced stuff such as Presale, Public Sale, Discounts, goal, hard cap etc.. check out my latest article.

Lately I have been digging into blockchain and decentralised apps to educate myself and improve my knowledge. To make the learning process fun I decided to build my own Ethereum based token and understand the process of launching an ICO (Initial Coin Offering).

This article aims to give you an overview of how smart contracts work in Ethereum by launching a simple demo ICO.

Make Hashnode your discussion hub for all things crypto. Check out our crypto communities and join the blockchain-related discussions.

Basics

Here are a few basic terms we are going to use in this article. If you are familiar with the following concepts, feel free to skip to the next section.

Ethereum based ERC20 Tokens: In Ethereum tokens represent any tradable goods such as coins, loyalty points etc. You can create your own crypto-currencies based on Ethereum. Additionally the benefit of following ERC20 standard is that your tokens will be compatible with any other client or wallets that use the same standards.

Smart Contracts: Smart Contracts are self executing code blocks deployed on the Ethereum blockchain. They contain data & code functions. Contracts make decisions, interact with other contracts, store data and transfer Ether (the unit of crypto-currency in the Ethereum blockchain) among users.

Solidity: A language for writing smart contracts.

MetaMask/Mist/MEW Wallet: A digital facility that holds your Ether and other Ethereum based tokens.

Now that you are aware of the basic terminologies used in this article let's get started.

Step 1: Code

Open your favourite text editor and paste the following code:

pragma solidity ^ 0.4 .4 ; contract Token { function totalSupply () constant returns (uint256 supply) {} function balanceOf (address _owner) constant returns (uint256 balance) {} function transfer (address _to, uint256 _value) returns (bool success) {} function transferFrom (address _from, address _to, uint256 _value) returns (bool success) {} function approve (address _spender, uint256 _value) returns (bool success) {} function allowance (address _owner, address _spender) constant returns (uint256 remaining) {} event Transfer(address indexed _from, address indexed _to, uint256 _value); event Approval(address indexed _owner, address indexed _spender, uint256 _value); } contract StandardToken is Token { function transfer (address _to, uint256 _value) returns (bool success) { if (balances[msg.sender] >= _value && _value > 0 ) { balances[msg.sender] -= _value; balances[_to] += _value; Transfer(msg.sender, _to, _value); return true ; } else { return false ; } } function transferFrom (address _from, address _to, uint256 _value) returns (bool success) { if (balances[_from] >= _value && allowed[_from][msg.sender] >= _value && _value > 0 ) { balances[_to] += _value; balances[_from] -= _value; allowed[_from][msg.sender] -= _value; Transfer(_from, _to, _value); return true ; } else { return false ; } } function balanceOf (address _owner) constant returns (uint256 balance) { return balances[_owner]; } function approve (address _spender, uint256 _value) returns (bool success) { allowed[msg.sender][_spender] = _value; Approval(msg.sender, _spender, _value); return true ; } function allowance (address _owner, address _spender) constant returns (uint256 remaining) { return allowed[_owner][_spender]; } mapping (address => uint256) balances; mapping (address => mapping (address => uint256)) allowed; uint256 public totalSupply; } contract HashnodeTestCoin is StandardToken { string public name; uint8 public decimals; string public symbol; string public version = 'H1.0' ; uint256 public unitsOneEthCanBuy; uint256 public totalEthInWei; address public fundsWallet; function HashnodeTestCoin () { balances[msg.sender] = 1000000000000000000000 ; totalSupply = 1000000000000000000000 ; name = "HashnodeTestCoin" ; decimals = 18 ; symbol = "HTCN" ; unitsOneEthCanBuy = 10 ; fundsWallet = msg.sender; } function () payable { totalEthInWei = totalEthInWei + msg.value; uint256 amount = msg.value * unitsOneEthCanBuy; require (balances[fundsWallet] >= amount); balances[fundsWallet] = balances[fundsWallet] - amount; balances[msg.sender] = balances[msg.sender] + amount; Transfer(fundsWallet, msg.sender, amount); fundsWallet.transfer(msg.value); } function approveAndCall (address _spender, uint256 _value, bytes _extraData) returns (bool success) { allowed[msg.sender][_spender] = _value; Approval(msg.sender, _spender, _value); if (!_spender.call(bytes4(bytes32(sha3( "receiveApproval(address,uint256,address,bytes)" ))), msg.sender, _value, this, _extraData)) { throw ; } return true ; } }

Based on the original source from Token-Factory.

The above code uses Solidity language to build a simple ERC20 token. The code is well commented and is very easy to understand. Once you paste the code into your text editor, find the text: "CHANGE THIS". This is what you need to change based on the characteristics of your token. In the example above, I have named my token HashnodeTestCoin (HTCN). The total supply is capped at 1000, but people can possess as little as 0.000000000000000001 because of 18 decimal places. Additionally, the owner of the contract (one who executes it) gets all the initial tokens. I have set the ICO price as following:

1 ETH = 10 HTCN

This means, if someone sends 1 ETH to this smart contract, they will get 10 HTCN units.

Step 2

Download MetaMask chrome extension to generate a wallet. This is going to be the owner of the smart contract. Alternatively you can always use Mist or My Ether Wallet. For the sake of simplicity let's use MetaMask extension in this project.

Once you download the extension, go ahead and create a new account protected by a password. Then choose "Ropsten TestNet" from the top left corner. Before we deploy the contract to Main Ethereum blockchain, we'll test it against TestNet and make sure everything works as expected. It looks something like this:

Now head over to Remix IDE (an online solidity compiler and debugger) and paste the code you just modified. Ignore any warnings you see. Next go to settings and uncheck "Enable Optimizations" if it's checked.

Now go to "Run" tab and click on create under <your token name>.

Once you hit create, MetaMask will prompt you to buy some test ether and submit the transaction. It looks something like this:

Just make sure you are on Ropsten TestNet and not on the MainNet and then hit Submit. Now open up MetaMask again and click on the first transaction. It'll take you to Etherscan where you can observe the ongoing transaction. It may take up to 30s to confirm the transaction. Once it's confirmed it looks like the following:

Viola!! You just deployed your contract. Note the to address in the above transaction page. That's your contract address.

Now it's time to verify if it actually works.

Step 3

Ideally if you've set up everything correctly you should receive all the initial tokens (1000 in my case) when you add it to your wallet. So, copy the contract address, go to MetaMask -> Add Token and paste the address. It looks like the following:

Hit Add and refresh MetaMask. You should now see all the initial supply (in my case it was 1000 HTCN). :)

Step 4

Now that everything works perfectly we just have to verify our smart contract so that everyone on the blockchain can read and understand it. It's always a good practice to verify since it helps establish trust.

Now go to your contract address and click on Contract Code tab.

.

Now click on "verify and publish" link. Once you are taken to the new page, fill up the details such as compiler version, Enable Optimizations etc and paste the solidity source we compiled in the first step.

Make sure the compiler version you choose matches the one you compiled your code against in the first step. Now hit "verify and publish". If successful, it'll generate bytecode and ABI as following:

Congrats! Now anyone can visit your contract address and read the source.

Step 5

To deploy your contract to production, you just need to switch TestNet to MainNet on MetaMask (located at top left corner) and repeat step 2 to 4. Please be aware that you will have to spend real Ether over there to deploy your contract. So, don't deploy the contract unless you are fully ready (Contracts are immutable and can't be updated once deployed). We'll keep using TestNet in this tutorial.

Buying tokens with Ether

As a part of the ICO, your users will buy tokens from you by paying ETH. Remember we set the price as 1 ETH = 10 HTCN while deploying the contract? So, if a user wants to buy 10 HTCNs through your ICO, they have to pay 1 ETH. Let's test this out.

Go to MetaMask, create a new account and load it with some Test Ether. Once the account is loaded, click "Send" and fill up your contract address. In the amount field, enter 2 (ETH).

Next, send 2 ETH to the contract address and wait for the transaction to be confirmed. Refresh MetaMask and check your tokens after a few seconds. The new test account should have got 20 HTCNs (or something different depending on your config) and the contract owner (you) should have 980 (or something similar) tokens.

Additionally, you should have received 2 ETH.

Congrats on the success!

Launching an ICO page

To display the amount of ETH raised by our project, we'll use a JavaScript library called Web3.js on our website.

Head over to Hashnode Test Coin ICO and check out the code in the last <script> tag. It's fairly simple and just uses Web3.js and ABI obtained from your contract.

Congrats if you have made this far! Do keep in mind that real production grade contracts and ICOs take significant efforts and are supported by thorough tests. While this tutorial gives you an overview of writing contracts for ICOs, it's never meant for production level deployment. Don't deploy this on MainNet without proper testing!

Thanks for reading this article. If you have any questions, please feel free to comment below.

Have blockchain-related questions? Check out these crypto communities on Hashnode and start a discussion.