Initial Coin Offering je stále buzzword či už v každodenných správach z technologického sveta alebo v našom okolí v komunite. Túto tému som už rozoberal v jednom z mojich blogov z minulého mesiaca, kde sme si prešli čo to vlastne je a ako to funguje. No rád by som sa pozrel v tomto blogu aj na to, ako ICO vyzerá z organizačnej a developerskej perspektívy.

Kickstarter na steroidoch + Ethereum Blockchain = ICO

Ako všetky projekty, aj tento musí začať dobrým nápadom. Vy ako founder, musíte mať v tom úplne jasno, či už podľa hotového white papera, alebo pokiaľ ešte nieje spísaný vo finálnej podobe, musíte mať spísanú presnú špecifikáciu.
Ako prvé, treba pripraviť landing page pre ICO status skôr než sa spustí marketingová kampaň. Súhra všetkých elementov do toho zapojených či už landing page, sociálne siete a napr. adwordsy musí byť dokonalá marketingová symfónia. Ale to je už skôr téma na iný blog.

 

Špecifikácia

Softvérové firmy v súčasnosti sa riadia bodmi manifestácie agilného vývoja, no pri smart contractoch a vývoji na ethereovom blockchaine je to trochu komplikovanejšie. Nesmieme zabúdať na dôležitú vlastnosť, ktoré smart contracty majú a to je práve ich nemennosť, keď sú už raz na blockchaine spustené. To znamená, že pred samotným spustením musí byť kód riadne otestovaný, musia byť vychytané aj tie najnenápadnejšie bugy a najmä musí prejsť aj testovaním bezpečnosti. Raz keď ho spustíte, nieje cesta späť. Samozrejme existujú možnosti ako updatnúť contract alebo opraviť bug ale je to komplikácia pri ktorej je lepšie ak by nebola. Každá zmena a každý bug ktorý vypláva na verejnosť znižuje kredit v komunite a čo sa môže odraziť v cenách pri zamieňaní tokenu/coinu. Preto je dôležité máť jasno v špecifikácii ešte pred samotným začiatkom.

 

Dôležité detaily o ktorých musí byť pred začiatkom rozhodnuté

Obyčajne by sa malo začať so štandardným tokenom ERC20 token. Potrebujete vedieť, ako sa váš token bude volať a jeho symbol. Taktiež je potrebné rozhodnúť, či množstvo/objem tokenu bude konečný, resp. obmedzený. Treba zvážiť zahrnutie inflačného a deflačného mechanizmu pokiaľ to vyžaduje špecifikácia. Veľa prvotných rozhodnutí a nastavení parametrov veľmi záleží od projektu. Existuje pre každé ICO niekoľko základných parametrov v ktorých je potrebné mať jasno:

  • dátum spustenia
  • dátum ukončenia
  • minimálny a maximálny požadovaný kapitál
  • mena v ktorej budú vyjadrené

Povedzme, že štvortýždňové ICO potrebuje vyzbierať minimum 1000ETH a maximum 20000ETH. Takéto záležitosti musia byť zahrnuté a implementované už v kóde pretože tokeny sa môžu veľmi rýchlo míňať a je potrebné včas ICO uzavrieť. Je veľmi dôležité myslieť aj na možnosť rýchleho pozastavenia alebo zdržania v prípade, že sa objaveý nejaký security bug alebo iný problém. Je XY prípadov a spôsobov ako môže ICO vyzerať a na čo všetko treba myslieť, ale ako som už písal hore, veľmi to záleží od povahy projektu. Z asi najbežnejších prípadov môžeme vybrať niekoľko možností ako sa môže ICO správať.

  • Tokeny budú prístupné okamžite po transakcii alebo až keď sa ICO ukončí.
  • ICO môže byť spustené predčasne ako presale len pre uzavretú skupinku ľudí/investorov.
  • ICO môže ponúkať možnosť bonusu pre prvých kupujúcich.
  • Vyzbierané prostriedky môžu byť v prípade nedosiahnutia cieľa vrátené.
  • Zakladatelia môžu dostať nejakú časť tokenov.
  • Prostriedky vyzbierané na ICO môžu byť uvoľňované periodicky alebo pod určitými podmienkami.
  • Vyzbieraný ether môže byť uložený v kontrakte alebo preposlaný do peňaženky(kôli bezpečnosti sa určite odporúča nezadržiavať prostriedky v kontrakte ale okamžite ich prevádzať do zabezpečenej peňaženky alebo “multisignature” peňaženky)

 

Implementácia, testovanie a deployment

Nedá sa dostatočne zdôrazniť miera potreby testovania contractu skôr, než je deploynutý na ostrú sieť. Treba si uvedomiť že týmto budeme manipulovať reálnymi peniazmi a zároveň nie malou sumou. Často ide o celé milióny dolárov, takže to, čo vypustíte na ostrú prevádzku musí byť otestované na 1000% a zároveň na takej úrovni, že testery NASA sa budú hanbiť. Dôležitosť bezchybnosti kódu sa dá prirovnať k programovaniu softwaru pre Mars Rover. Raz keď je hore, už nie cesty späť a ani žiadna možnosť, ako spraviť zmenu bez následkov.

Nástroje
Ako príklad pre tento článok si vytvoríme testovacie ICO v úplne jednoduchej, základnej podobe, čisto pre prezentačné účely. Čo sa týka technických vecí ako nástroje a ich inštalácia tu nebudem do detailov rozoberať, všetko je detailne rozpísané v tomto tutoriále:

#1 Ethereum DApp Tutorial: Intro do Smart Contractov

Takže pre naše testovacie ICO budeme potrebovať:

  • Solidity ako programovací jazyk
  • OpenZeppelin Solidity Contracts ako štandard a zákalad pre naše kontrakty
  • Truffle framework ako testovací a buildovací nástroj
  • Testrpc pre simuláciu Ethereum blockchainu
  • MyEtherWallet.com pre spustenie kontraktu na Ethereum blockchaine

Upresníme si špecifikáciu
Využijeme špecifikáciu spomenutú už hore spolu s dodatočnými bodmi ako:

  1. Spúšťame základný ERC20 token s názvom “Ondro Test Token” so symbolom “DRB” a 18 desatinnými miestami rovnako ako najmenšia jednotka etherea – wei, s konečným objemom 1 000 000 jednotiek, vytvorených počas spustenia a priradené k špecifickej peňaženke.
  2. ICO bude trvať 4 týždne a jeho cieľom bude vyzbierať minimálne 1000ETH a maximálne 20000ETH s tým, že pokiaľ cieľ nebude splnený, ICO beží až kým sa nedosiahne minimálna cieľová suma.
  3. Vyzbierané ETH budú preposielané do špecifickej peňaženky po každej platbe.
  4. Tokeny budú k dispozícii iba pre transakcie až po ukončení ICO.
  5. Tokeny sa budú predávať s prepočtom 1 ETH : 50 DRB s +50% bonusom počas prvého týždňa.

 

Implementácia

Rovnako ako sme to robili v tutoriále k základom smart contractov, vytvoríme si novú zložku kde chceme mať projekt uložený, v terminále v tej zložke spustíme truffle init, príkaz ktorý nám vytvorí nový základný bundle pre tvorbu smart contractov. V zložke contracts si vytvoríme nový súbor pre náš token contract s príponou .sol.

V root zložke ešte pred začatím spustíme príkaz:

npm install --save zeppelin-solidity

Kód do súboru môžeme skopírovať odtiaľ:

pragma solidity ^0.4.15;

import 'zeppelin-solidity/contracts/token/ERC20Basic.sol';
import 'zeppelin-solidity/contracts/token/StandardToken.sol';


contract OndroTokenIco is StandardToken {
    using SafeMath for uint256;

    string public name = "Nazov Tokeny";
    string public symbol = "SYMBOL";
    uint256 public decimals = 18;

    uint256 public totalSupply = 1000000 * (uint256(10) ** decimals);
    uint256 public totalRaised; // celková raisovaná suma vyjadrená vo wei

    uint256 public startTimestamp = 1506420013; // timestamp kód po ktorom ICO bude spustené
    uint256 public durationSeconds = 4 * 7 * 24 * 60 * 60; // 4 týždne

    uint256 public minCap = 1; // minimálna cieľová suma (wei)
    uint256 public maxCap = 1;// maximálna cieľová suma (wei)

    /**
     * Adresa ktorá získa všetky vyzbierané prostriedky
     * a zároveň vlastní všetky tokeny
     */
    address public fundsWallet = 0xb4F3422761CF46b868A48e269114784876d67966;/*Tu daj svoju vlastnú adresu*/

    function OndroTokenIco(
        /*address _fundsWallet,*/
        /*uint256 _startTimestamp,
        uint256 _minCap,
        uint256 _maxCap) {
        fundsWallet = _fundsWallet;
        startTimestamp = _startTimestamp;
        minCap = _minCap;
        maxCap = _maxCap;*/

        // prideľ všetky tokeny do uvedenej adresy
        balances[fundsWallet] = totalSupply;
        Transfer(0x0, fundsWallet, totalSupply);
    }

    function() isIcoOpen payable {
        totalRaised = totalRaised.add(msg.value);

        uint256 tokenAmount = calculateTokenAmount(msg.value);
        balances[fundsWallet] = balances[fundsWallet].sub(tokenAmount);
        balances[msg.sender] = balances[msg.sender].add(tokenAmount);
        Transfer(fundsWallet, msg.sender, tokenAmount);

        // okamžite preveď do uvedenej adresy
        fundsWallet.transfer(msg.value);
    }

    function calculateTokenAmount(uint256 weiAmount) constant returns(uint256) {
        // štandardný konverzný pomer: 1 ETH : 50 DRB
        uint256 tokenAmount = weiAmount.mul(50);
        if (now <= startTimestamp + 7 days) {
            // +50% bonus počas prvého týždňa
            return tokenAmount.mul(150).div(100);
        } else {
            return tokenAmount;
        }
    }

    function transfer(address _to, uint _value) isIcoFinished returns (bool) {
        return super.transfer(_to, _value);
    }

    function transferFrom(address _from, address _to, uint _value) isIcoFinished returns (bool) {
        return super.transferFrom(_from, _to, _value);
    }

    modifier isIcoOpen() {
        require(now >= startTimestamp);
        require(now <= (startTimestamp + durationSeconds) || totalRaised < minCap);
        require(totalRaised <= maxCap);
        _;
    }

    modifier isIcoFinished() {
        require(now >= startTimestamp);
        require(totalRaised >= maxCap || (now >= (startTimestamp + durationSeconds) && totalRaised >= minCap));
        _;
    }
}

Nezabudúmae definovať, ktorý súbor sa má deploynúť:

var OndroTokenIco = artifacts.require("./OndroToken.sol");

module.exports = function(deployer) {
  deployer.deploy(OndroTokenIco);
};

Tento jednoduchý token, ktorý som hore popísal, je založený na štandardnom tokene od OpenZeppenin. OpenZeppelin je framework pre znovupoužitie základných, otestovaných a bezpečných smart contractov, čiže nám zabezpečí, že základ nášho tokenu máme otestovaný komunitou a expertmi v odbore a nemusíme sa báť bezpečnostných hrozieb.

 

Deployment

V tomto momente máme hotový otestovaný token smart contract a sme pripravení ho skompilovať použitím truffle frameworku a deploynúť ho na blockchain použitím MyEtherWallet.com.

Skôr než začneme samotný deploy, musíme si pripraviť testovacie peňaženky, privátne kľúče a nejaký ten testovací roopsten ether.

Na MEW sa v prvom rade uistíme, že sa nachádzame na testovacej sieti (Ropsten). Klikneme na “Deploy Contract” a v tejto sekcii budeme potrebovať zopár informácii z nášho kódu.
Vrátime sa späť do konzoly a zadáme príkaz truffle compile. Pokiaľ sme všetko spravili správne, kompilácia kódu prebehla bez problémov a v zložke “build” sa nám vytvorili súbory. Zo súboru “OndroTokenIco.json” skopírujeme byte kód ako je uvedený v screenshote.
Snímka obrazovky 2017-09-26 o 21.06.18

Tento kód pastneme do položky “Byte Code” a automaticky sa nám vygeneruje “Gas Limit”. V tejto časti použijeme nainštalovaný MetaMask pri ktorom sa taktiež uistíme, že ho máme prepnutý na Roopsten test network.

V časti “How would you like to access your wallet” sa dá použiť aj možnosť automatického spojenia s MetaMask ale mne to z nejakého dôvodu nefungovalo, takže som si vytvoril na MEW novú peňaženku, z MetaMasku som si tam previedol zopár ETH a private key som použil pre napojenie na deploy zvolením možnosti “Private Key”.

ico1

Ostáva nám už len kliknúť na “Deploy Contract”, v dolnej časti sa nám zobrazí adresa na ktorú keď klikneme, môžeme sledovať minovanie contractu. V tomto momente máme contract deploynutý.

Po vyminovaní contractu, pomocou etherscan si môžeme vyhľadať naše ICO pomocou skratky alebo jeho symbolu. V mojom prípade je to tento 0x19f7997bf4323ae3cac5fa5e40e599db4a8ef71c.

ico2

V záložke “Token Transfers” môžeme vidieť že tokeny nám boli presunuté na peňaženku ktorú sme si určili. Môžeme si ju cez MEW skontrolovať, kde v pravom dolnom rohu si dáme načítať “Token Balances”.

ico3

Ako vidíme v priloženom screenshote, všetko s kontraktom sedí, máme svoje tokeny a šťastní môžeme vytvoriť landing page a spustiť marketingovú kampaň s propagáciou nášho ICO a pomaly pripravovať ľudí na “deň-d”, resp. “deň-ico”.

 

Čo ak ale potrebujeme contract predsa len zmeniť?

Token je spustený, práve prebieha ICO a akurát ste si všimli závažný bug ktorý sa nedá odignorovať a potrebuje byť ASAP opravený. Ako som spomínal vyššie, raz keď je contract von, nedá sa zmeniť. Našťastie existuje viacero spôsobov ako napraviť vzniknutú chybu. Treba mať ale na zreteli, že snažíte sa meniť contract s ktorým už ľudia interagovali. Nieje to rozhodnutie ktoré by som bral na ľahkú váhu.

Naznámejšou z možností ako updatnúť contract je upload nového a informovanie ľudí o zmene. To ale nieje úplne také jednoduché. Pravidlo ktoré pozná každý programátor je, že ak raz nájdete po dlhom testovaní jeden bug, pravdepodobne tam bude po jeho fixnutí skrytý ďalší, preto je potrebne znova spustiť celý kolobeh revízií, testovaní a auditov, skôr, než ho znova deploynete von.
Ďalšia závažná vec je naplánovanie migrácie dát z chybného contractu . Povedzme že potrebujete premigrovať objemy transakcií z chybného contractu do nového. Najjednoduchšia cesta ako to dosiahnúť je zavolať funkciu balanceOf() z ERC20 ktorá dokáže prečítať objemy z pridelených adries. Potom stačí už len prideliť dáta z funkcie do nového kontraktu.

Veľmi dôležité je o všetkom informovať komunitu a investorov. Je dôležité vysvetliť čo a prečo sa to udialo a zároveň informovať o dočasnom pozastavení ICO, dokiaľ nebude nový contract deploynutý s novou adresou.

Týmto tutoriálom som sa snažil nadviazať na predošlé tutoriály k smart contractom a snáď som vám priblížil aspoň z časti ako reálne ICO vyzerá po technickej stránke.
Nabudúce pripravým blog o tom, ako ďalej manipulovať s tokenmi a čo všetko s nimi dokážeme spraviť.

 

 

Ak ťa článok zaujal a chceš sa pustiť do technických záležitostí, môžeš pokračovať týmto:

#1 Ethereum DApp Tutorial: Intro do Smart Contractov

Ak zatiaľ nevlastníš žiaden Eher ani Bitcoin, môžeš to urobiť pomocou môjho návodu:

Deň keď pršia peniaze alebo prvé kroky k Bitcoinu a Ethereu

0