Smart contracts Ethereum: write a simple contract for ICO

lately I receive a huge number of requests for assistance in the development of smartcontract for carrying out ICO, I have not enough time to help everyone. So I decided to write this small post (link to video at end of post), which describe a very simple smartcontract to conduct a crowdsale, which you can use in your projects.



To save time I wrote the contract in advance. Let's break it down.

Smartcontract is a program written in a programming language. In our case, the language of Solidity. To design simple contracts I use an online editor and compiler Remix.

A good practice is to start any program, including smartcontract, providing a license, based on which it applies. In our case it is GPL. You can also specify yourself as the author of the contract, of course, if you are writing a contract for some skipovogo project, which I hesitate to specify yourself as the author.

the
/*
This file is part of the EasyCrowdsale Contract.

The Contract EasyCrowdsale is free software: you can redistribute it and/or
modify it under the terms of the GNU lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

The EasyCrowdsale Contract is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU lesser General Public License for more details.

You should have received a copy of the GNU lesser General Public License
along with the EasyCrowdsale Contract. If not, see <http://www.gnu.org/licenses/>.

@author Ilya Svirin <i.svirin@prover.io>
*/

Immediately following is a string that indicates what version of kompillyator should be used. If this line is not, then smartcontract will not compile.

the
pragma solidity ^0.4.0;

Next comes the source code directly to smartcontract that I have structured into a hierarchy of contracts, each of which implements the complete functionality. This simplifies the understanding and subsequent use of the code in your contract.

First of all, it should be understood that after loading smartcontract in the Ethereum virtual machine you will interact with them on a common basis, as all other users. It is logical that we as a project team, I would like to be in privileged conditions, which should at least be expressed that the contract should form it on the command tokens and of course gave us the collected air. To do this, a contract should know its owner and it is responsible for this contract "owned".

the
contract owned {

address public owner;

function owned() payable {
owner = msg.sender;
}

modifier onlyOwner {
require(owner == msg.sender);
_;
}

function changeOwner(address _owner) onlyOwner public {
owner = _owner;
}
}

The contract is "owned" only contains one public field "owner" whose value is initialized in the constructor a value for the field "sender" global structure "msg", thus, the original owner of the contract is the one who implemented it and deploy.

It is logical to consider the possibility of a change of ownership in case our private key is compromised, for this the function "changeOwner", which receives as parameter the address of the new owner. Should be paid to the modifier "onlyOwner" which is defined inside smartcontract. Modifiers represent a very convenient design allows users to group and assign a name to the conditions of calling functions smartcontract. The modifier "onlyOwner" checks that the function call is performed from an address which is stored in field "owner".

The contract is "owned" fully functional and extremely simple, but carries a hidden threat, because when calling a function "changeOwner" we might specify a non-existent address, and therefore lose control over the contract. To correct this deficiency, it is enough to enter another field, call it "candidate", and when calling the function "changeOwner" will save the new value first in the "candidate" and move it to the "owner" will be once the candidate confirms his entry into law, calling from his address option "confirmOwner".
Next in the hierarchy of contract "Crowdsale", responsible for the collection of funds and issuance of tokens and inherits the previous contract "owned".

the
contract Crowdsale is owned {

uint256 public totalSupply;
mapping (address = > uint256) balanceOf public;

event Transfer(address indexed from indexed address to, uint256 value);

Crowdsale function() payable owned() {
totalSupply = was 21000000;
balanceOf[this] = 20000000;
balanceOf[owner] = totalSupply - balanceOf[this];
Transfer(this, owner, balanceOf[owner]);
}

function () payable {
require(balanceOf[this] > 0);
uint256 tokensPerOneEther = 5000;
uint256 tokens = tokensPerOneEther * msg.value / 1000000000000000000;
if (tokens > balanceOf[this]) {
tokens = balanceOf[this];
valueWei uint = tokens * 1000000000000000000 / tokensPerOneEther;
msg.sender.transfer(msg.value - valueWei);
}
require(tokens > 0);
balanceOf[msg.sender] += tokens;
balanceOf[this] -= tokens;
Transfer(this, msg.sender, tokens);
}
}

Special attention should be paid to the following elements of the contract:

the
    the
  • a Public field "totalSupply", which shall contain the total number of tokens issued by smartcontract;
  • the
  • map of Public "balanceOf", which contains information about the balance sheets of all holders of the tokens;
  • the
  • Event Transfer, which is emitted by smartcontract every move tokens between the token holders.

All these three elements have one thing in common, they are an essential part of the standard ERC20 that must be followed to information about our token is correctly displayed in the wallets of users and etherscan.io.

Designer smartcontract "Crowdsale" is extremely simple. First of all initialized to the value of the field "totalSupply". Our contract produces 21 million tokens, of which 20 million will be immediately moved to the balance of smartcontract. We assume that tokens with addresses of smartcontract just available for sale. The remaining tokens, in our case, 1 million will be written to the address of the owner of the contract. Well, at the end of the constructor event is emitted "Transfer", which is placed in the blockchain and informs users of the contract that the balance of the contract on the balance sheet of the owner of the contract transferred the corresponding amount of tokens. It is the emission of this event will allow etherscan.io to correctly display token holders and their balances.

Well, the major function of smartcontract "Crowdsale", so-called fallback function which is called every time the broadcast comes to our smartcontract. In the beginning check that on the balance of smartcontract have any number of tokens for sale. Next install the fixed price tokens – 5000 pieces per 1 ether. Then calculate how many tokens you want to send to the sender of the broadcast. The number transmitted in the transaction of the funds is written in the "value" global structure "msg" and indicated it is in "wei", so when determining the number of tokens translate to "wei" in "ether".

The system then checks that the balance of smartcontract there are enough tokens for sale. If requested more tokens than have smartcontract, it will transfer all the remaining tokens. Determine the cost to "wei" remaining tokens and returned to the sender unnecessarily translated live. Make sure that the number of tokens purchased are non-zero, then we write this number of tokens on the balance sheet of the buyer and write off their balance smartcontract. In the end don't forget to emit the event Transfer.

This is the actual implementation of the functionality of the fundraiser is finished, but now need to make our token and operable to implement some functions of the standard ERC20. It is made in the contract "EasyToken", which inherits from the previously discussed contract "Crowdsale".

the
contract EasyToken is Crowdsale {

public string standard = 'Token ' 0.1';
public string name = 'EasyTokens';
public string symbol = "ETN";
public uint8 decimals = 0;

EasyToken function() payable Crowdsale() {}

function transfer(address _to, uint256 _value) public {
require(balanceOf[msg.sender] >= _value);
balanceOf[msg.sender] -= _value;
balanceOf[_to] += _value;
Transfer(msg.sender, _to, _value);
}
}


Finally, the only function of smartcontract "EasyToken" for which we created this contract is a "transfer," which is also part of the standard ERC20 and wallets will allow users to transfer tokens to each other, transfer them to the exchange and withdraw them from it. The function implementation is very simple, it is checked whether the number of tokens on the balance of the sender, after which the balance of the sender is reduced and the balance of the receiver is increased by the requested number of tokens. At the end event is emitted "Transfer". Now our token is operable and left to do the most important thing is to provide the owner of the contract the possibility to withdraw the collected ethers. This we shall do in the contract "EasyCrowdsale".

the
contract EasyCrowdsale is EasyToken {

EasyCrowdsale function() payable EasyToken() {}

function withdraw() public onlyOwner {
owner.transfer(this.balance);
}
}

The function "withdraw" has the modifier "onlyOwner", i.e. it can be invoked only by the owner of smartcontract. The only thing it does – it puts the entire balance of smartcontract to the address of the owner of smartcontract.

Despite the fact that we considered smartcontract is fully functionally complete and operable, use it in a real project I would not recommend. An oversimplification of the logic of the contract led to the fact that such a contract does not protect the interests of investors in due measure, namely, does not establish the duration of the crowdsale, does not establish a minimum fee, does not return funds to investors in case of failure to achieve the minimum border, as well as contains a number of known vulnerabilities at the level of the language compiler, Solidity, for example, is subject to the so-called short address attack.

Many of these disadvantages are eliminated in smartcontract of our project PROVER. Contract PROOF loaded in Ethereum at this location along with the source code, with which you can interact. You can even check the work of the contract, sending it to the real live, we just now there is a Pre-ICO:). In fact, we will be glad, if you join the presale of our project PROVER, which will last until the end of September. PROVER is a unique technology to confirm the authenticity of videos on the basis of the blockchain and video analysis.

Useful links:

the
Article based on information from habrahabr.ru

Комментарии

Популярные сообщения из этого блога

When the basin is small, or it's time to choose VPS server

Performance comparison of hierarchical models, Django and PostgreSQL

From Tomsk to Silicon Valley and Back