ICO – Simple. Too simple.

ICO – Simple. Too simple.

important notice, please read!

This post blog is for educational purposes only. Solidity and Ethereum are bleeding edge technologies and should be treated with respect. Make sure to properly educate yourself before attempting to implement any code you might find online. I can attest that the code provided here is without a doubt not secure. It’s (at the very least) susceptible to overflow attacks, short address attacks and transferFrom double spend attacks. This is actually a very good example to my point because, while being open to such attacks, my code does adhere to the ERC20 standard. Use this code to get yourself familiarized with the basics, and then keep on learning.


All that glitters is gold.

As of April 2017, there’re 161 ICOs listed on TokenMarket, one of the leading token platforms. Of these 161 ICOs, 118 were still active. Almost every new company in the blockchain ecosystem choose ICO as its main source of fund raising.

Offering shares in the form of coins is a great way for raising funds and for potential investors to invest in many of the new and exiting new projects out there. But here’s something most don’t know: Most ICOs are nothing more than copy-past of the same code that was used in a dozen of previous ICOs – AND RIGHTFULLY SO.

The reason the same code is used again and again (with moderate variations) lies at the fact that this code was developed and tested by professionals, and it provides many useful features both to the creators of 3rd party apps (like wallets and exchanges) but also to the end users, who can be somewhat assured that the tokens they’ve just bought can be used and exchanged with relative ease.


So what’s the problem?

It seems as if many of these companies also promise (or at least gives the vague impression) that the coins that they’re offering represents a substantial part of the final product. “Buy PizzaCoin at only 57 PZC per 1 ETH and you’ll be able to use these 57 PZC in our PizzApp store.” This promise alludes to the fact that such smart contracts/apps are already developed (or at the very least are in a finale stage of development). Which is usually not the case. While I can understand those who buys tokens in the hope that in the future they might be worth more on the market (speculates) I also believe that a substantial part of the investors in ICOs hope to utilize these coins in their respective apps. They just don’t know how generic the coin really is.

Also, many of these generic contracts sometimes issue coins in a rate that has very little economic reason behind it (what does it mean to get 57PZC? Is that mean that each coin will be equal one pizza in the future? Will the price of future pizza will be determinate in a coin exchange? How do you calculate the cost of operating and maintaining a smart contract that doesn’t exist yet?).

I have absolutely no doubt that many companies actually using the raised funds in a responsible manner. They’re working hard to deliver a real final product, and I’m sure that there’re also many investors who understand that these ICOs tokens are usually nothing more than a financial assets (at least at this early stage) and the fact that they’re issued using a generic contract is not a surprise to them, but there are many others who don’t. And for them, I dedicate this post.

I hope you’ll find it useful.

ERC20 Tokens


Step one – Secure operators

Ethereum Virtual Machine (EVM) is susceptible to overflows and memory offsets. Fortunately, that can be solved quite easily by implementing some simple function to perform basic operations. Zeppelin team provided us with the SafeMath contract that provides us with the functions safeAdd, safeMul, safeDiv, safeSub and assert (The other functions are not relevant for this tutorial). Using the assert function, the SafeMath functions results are checked to make sure that they adhere to what is expected of them. For example: The function safeAdd receives two unsigned integers (a, b) and sum them together to get the result c. While both a and b are uint (not negative numbers) there’s still a chance that due to an overflow, the final result c will be lower than the sum of its components. That’s why the SafeMath function also checks to make sure that c is indeed larger then a.


Step two – ERC20 functions signatures

In late 2015 Fabian Vogelsteller, one of the mist wallet developers, suggested the creation of a unified token template called ERC20. The idea was that by providing a unified architecture for tokens – wallets creators, exchanges, and other service providers could produce a product that will support these token right out of the box, without having the need to recreate a unique wallet for each new token that is issued over the Ethereum protocol. It was suggested that the following functions will become the standard for every new token contract.

function totalSupply() constant returns (uint256 totalSupply) {}
function balanceOf(address _owner) constant returns (uint256 balance) {}
function transfer(address _recipient, uint256 _value) returns (bool success) {}
function transferFrom(address _from, address _recipient, 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 _recipient, uint256 _value);
event Approval(address indexed _owner, address indexed _spender, uint256 _value);


While this standard isn’t fully accepted (and enforced), many token developers adhere to it as it provides them with many benefits, especially regarding interacting with other Ethereum services.

The functions signature suppose to match the basic functionality that is expected from every token smart contract.

  • function totalSupply: Display the total supply of your tokens.
  • function balanceOf: Display the amount of tokens each account has.
  • function transfer: Send value (amount of tokens) to address (recipient). The sender address is usually msg.sender.
  • function approve: Give permission to another account to trade tokens on your behalf. Used mostly when splitting your tokens to multiple wallet accounts and/or exchanges.
  • function transferFrom: Just like transfer, only in this case the user needs to specify the sender address as well.
  • function allowance: Display the amount of tokens that can be spent on behalf of the token owner by each approved address
  • event Transfer: Indexing all transactions by sender and recipient, also specify the transferred amount of tokens.
  • event Approval: Indexed all approved accounts by owner and spender account address, also specify the amount of tokens the sub spender can spend.


Step three – write your functions

Simple and straight forward. We need to start to populate our functions. Pay attention that these functions need to match the function signatures mentioned above.

mapping(address => uint256) balances;

uint256 public totalSupply;

function balanceOf(address _owner) constant returns (uint256 balance) {
    return balances[_owner];

function transfer(address _to, uint256 _value) returns (bool success){
    balances[msg.sender] = safeSub(balances[msg.sender], _value);
    balances[_to] = safeAdd(balances[_to], _value);
    Transfer(msg.sender, _to, _value);

mapping (address => mapping (address => uint256)) allowed;

function transferFrom(address _from, address _to, uint256 _value) {
    var _allowance = allowed[_from][msg.sender];
    balances[_to] = safeAdd(balances[_to], _value);
    balances[_from] = safeSub(balances[_from], _value);
    allowed[_from][msg.sender] = safeSub(_allowance, _value);
    Transfer(_from, _to, _value);

function approve(address _spender, uint256 _value) {
    allowed[msg.sender][_spender] = _value;
    Approval(msg.sender, _spender, _value);

function allowance(address _owner, address _spender) constant returns (uint256 remaining) {
    return allowed[_owner][_spender];

The totalSupply function was replaced by a simple uint public totalSupply.


Step four – Finalizing the token

Add the following parameters to your token contract:

string public name = "ShlomiCoin";
string public symbol = "SCO";
uint public decimals = 3;
uint256 public INITIAL_SUPPLY = 10000;
uint256 totalSupply;

Insert the token constructor function:

function ShlomiCoin() {
  totalSupply = INITIAL_SUPPLY;
  balances[msg.sender] = INITIAL_SUPPLY;  // Give all of the initial tokens to the contract deployer.

And finally mash it all together to get your token contract. (Full code on Github).


Make sure your token works correctly

Check your contract by opening your mist wallet, or go to wallet.ethereu.org (Web interface for your ethereum node). Under CONTRACTS you should see TOKENS. Just press WATCH TOKEN and insert your token address into the popup window. You should now see that you’re indeed the proud owner of 10,000 Shlomi coins.

Pay attention, this is a standard ERC20 token, but it’s not supporting crowd-selling yet. However, making sure that your token is working and is on per with the latest standard is a significant step on the way to create a stable ICO.

Add the token address to your “watched tokens” list


Under the Send tab, you can access your tokens and send them almost as if they were regular ethers



Get yourself a cup of coffee and get ready to offer your contract to the public.


The offering

Now that we know that we have a smart contract that works and is on per with modern standards, it’s time to offer it to the public.

This step is slightly less rigid than the previous one as there’re many ways and parameters in which one ICO is different from the other. Some might place a cap on the sale; some might have a time limit on the coin offering or have a different price for each step of the sell, some might send the etheres directly to the company issuing the ICO while others might split the ethers or freeze them or even destroy them. Sometimes the buyer might get the token immediately and sometimes only after a certain time passed – You get the picture. While ERC20 attempts to provide a uniform token standard, ICOs are the wild west.

But for this example, I decided to create an ICO which:

  1. Have uniform price throughout the sell.
  2. Stays open for exactly one week since being deployed.
  3. Immediately issue the tokens to the buyers.
  4. Sends the etheres to the owner (deployer) of the ICO contract (only one address).


Step one – Creating tokens function

A simple createTokens function will:

  1. Make sure that the transaction value isn’t empty (the buyer added ethers to the transaction).
  2. Calculate the amounts of tokens to be issued (price * amount).
  3. Update the new totalSupply variable with the new amount that was recently created.
  4. Adds the new tokens into the buyer (msg.sender) balance.
  5. Send the ethers to the owner of the ICO contract.


function () payable {

function createTokens(address recipient) payable {
	if (msg.value == 0) {

	uint tokens = safeDiv(safeMul(msg.value, price), 1 ether);
	totalSupply = safeAdd(totalSupply, tokens);

	balances[recipient] = safeAdd(balances[recipient], tokens);

	if (!owner.send(msg.value)) {

This function will be called automatically when ever someone sends money to the ICO contract by using the fallback function (function ()).


Step two – Create a modifier to prevents buyers from sending ethers after the offering period ended.

uint256 public endTime;

modifier during_offering_time(){
	if (now >= endTime){


Step three – add time limit, owner address and price to your token constructor

function ShlomiICO() {
	totalSupply = INITIAL_SUPPLY;
	balances[msg.sender] = INITIAL_SUPPLY;  // Give all of the initial tokens to the contract deployer.
	endTime = now + 1 weeks;
	owner = msg.sender;

And finally mash it all together to get your token contract. (Full code on Github).

You can now launch your ICO token and interact with it using mist (or any other compatible wallet). This token will work just like any other ERC20 token with one exception if during the time of offering someone will send it one ether, which senders will receive 500 tokens into their account, while the owner of the ICO contract will get that one ether into his/hers ether account.


Simple too simple.

Two points that I want to emphasis here, the first one is that this code is extra simplistic. There’re many more features, security mechanism, distributions schemes and functionalities that can be incorporated into both ERC20 contracts and ICOs. I don’t want to disparage anyone who issues tokens and offers them to the public. This is indeed hard work that requires a lot of research, careful planing and high level of expertise. IT REALLY ISN’T MEANT FOR ANYONE!

However, the code presented here is the real thing, it’s not the best example, but that’s the scaffolding on which most ICOs are based upon. Usually, there’s no actual mechanism that will incorporate these coins into a working application/smart contract – at least not at the time of ICO.

3 thoughts on “ICO – Simple. Too simple.

  1. Excellent article. It has been hard to find sample code and it’s not clear on the ethereun.org site that the bugs are fixed in their example code. Keep up the good work. It’s appreciated.

  2. Hi Shlomi,
    Thanks for your good work.
    I have an idea for a blockchain project, but I aren’t by any means a programmer. Im not sure where to start, so here it is… a begin.

Leave a Reply

Your email address will not be published. Required fields are marked *