#1 Ethereum DApp Tutorial: Intro do Smart Contractov

Pôvodne som chcel nadväzovať na minulý článok o Ethereum ICO o tom, ako spustiť svoje vlastné ICO, no uvedomil som si, že bez bližšieho vysvetlenia smart contractov to nepôjde. Preto som spísal krátky úvod s príkladom a návodom ako spustiť vlastné smart contracty.

Z minulých blogov už vieme, čo to je Blockchain a ako to funguje a máme už mierny nástrel čo je Ethereum a jeho smart contracty.

Smart Contract – (nenašiel som preklad do slovenčiny tak si ich pripôsobme do skratky SC).

SC sú najdôležitejšou súčasťou záujmu okolo Etherea. V minulom blogu sme si vysvetľovali ako funguje Blockchain a hovorili sme o jednotlivcoch sediacich v skupinke, ktorá si medzi sebou zaznamenáva transakcie. Vysvetlili sme si, že každý z nich si na svoju stránku zaznamenáva všetky transakcie, ktoré na sieti prebehnú a najmä to, že každý z nich vlastní svoj účet s vlastnými prostriedkami, ktoré môže posielať iným účastníkom v sieti.

Ethereum blockchain funguje na veľmi podobnom princípe s malými rozdielmi. Účty medzi ktorými prebiehajú transakcie neriadia priamo účastníci v sieti, ale namiesto nich ich riadí konkrétny set inštrukcií, ktorý je autonómny a nevyžaduje účasť ďalšej entity. Tento set inštrukcií si môžeme predstaviť ako kus počítačového kódu, ktorý dokáže vykonávať výpočty, ukladať informácie, určovať podmienky ktoré po vyplnení automaticky spustia akciu.

Kód SC, či konkrétne set inštrukcií, po napísaní programátorom sa uploaduje na ethereový blockchain kde si treba uvedomiť, že raz keď je takýto SC uploadnutý na blockchain, iba jeho logika určuje čo sa bude s účtom ďalej diať.

Kód je zákon

SC si v reálnom svete môžeme okrem setu inštrukcií predstaviť aj ako zmluvu medzi dvoma stranami. Keď podpisujeme resp. súhlasíme so zmluvou v reálnom svete, dôležitú rolu v akte hraje to, či sme porozumeli tomu čo sa chystáme podpísať a najmä či dôverujeme danej zmluve. V zmluve sú stanovené zmluvné podmienky, čo je to, k čomu sa podpisujeme, čomu rozumieme a súhlasíme s tým. Presne ako to robíme pri začiarknutí políčka “súhlasím so zmluvými podmienkami” pri rôznych registráciách na rôznych platformách a portáloch ako napríklad Spotify či iTunes. Predsa by sme nikomu neupísali svoje prvorodené dieťa ako to robí 99% užívateľov… všakže?

Na druhú stranu zmluvné podmienky ktoré sú spísané v zmluve sú obalené celou históriou práva a zákonov. To znamená že nie vždy si môžeme byť 100% istý že zmluve rozumieme a aj jej dôsledkom ktoré z nej vyplývajú len tým, že si zbežne prejdeme jej obsah. Existujú zákony, ktoré zakazujú upísať svoje prvorodené dieťa aj keď by sme to podpísali v zmluve. Vždy musíme jej kontextu rozumieť na 100%.

Aj keby sme hypoteticky upísali svojho prvorodeného potomka, stále je tu riziko že to podľa zmluvy nebude stačiť. Môžeme predať svoj majetok, rodinu do otroctva a stále podľa zmluvy to nebude stačiť. Riziko vstupu do zmluvy s niekým o kom si nemôžeme byť 100% istý že je schopný splniť jej podmienky sa nazýva “riziko protistrany” alebo kreditné (úverové) riziko a to je niečo čo pri podpise zmluvy musí byť taktiež zohľadnené.

Nakoniec asi posledná vec ktorej musíme rozumieť, resp. si ju uvedomovať pri uzatváraní zmluvy je viera v “právny štát”. Právny štát je štát, v ktorom vládne právo. Štát, štátne orgány môžu postupovať len na základe práva a len spôsobom ustanoveným právom. To je faktor ovplyvňujúci to, že určite nebudeme podpisovať zmluvu s Robkom Kalim pretože v tom prípade zmluva nestojí ani za ten papier na ktorom by bola vytlačená.

Ako si ale tieto faktory spojíme s SC? SC vo svojej samotnej podstate sú riadené dvoma faktormi ktorým treba rozumieť a dôverovať:

1. Zdrojový kód, ako je napísaný resp. interpretovaný
2. Neovplyvniteľnosť blockchainu

Ako pri zmluvách v reálnom svete, aj pri SC je dôležité rozumieť jeho obsahu. Zmluvy v reálnom svete sú interpretovateľné zákonmy. Pri SC je jeho obsahom zdrojový kód interpretovaný a čitateľný počítačom. Ako taký SC teda vyzerá? Príkladom nám môže byť tento kus kódu:

function payOut(address _recipient, uint _amount) returns (bool) {
	if (msg.sender != owner || msg.value > 0 || (payOwnerOnly && _recipient != owner))
		throw;
	if (_recipient.call.value(_amount)()) {
		PayOut(_recipient, _amount);
		return true;
	} else {
		return false;
	}
}

Samotný SC predstavuje zmluvné podmienky s ktorými súhlasite pri jeho používaní alebo interagovaní s ním. Rovnako ako dôverujete blockchainu na ktorom SC beží, tak musíte dôverovať aj samotnému SC, ktorý je vykonaný presne tak ako bol naprogramovaný, takže z toho logicky vyplýva že neexistuje žiadna možnosť ako zmluvu porušiť alebo ju interpretovať inak ako bol zamýšľaná.

O tom aký potenciál majú SC a kde všade môžu byť využité som už písal v skoršom článku(priložený pod odsekom) takže sa posuniem priamo k realizácii.

16 oblastí, ktoré Blockchain zmení

Napíšme si náš prvý Smart Contract

Veľa vývojárov sa sťažuje že Ethereum je veľmi náročné na logiku a ťažkopádne na použitie. Mne osobne učarovalo a snažím sa vzdelávať a nasávať nové a nové informácie pre moje budúce projekty, preto som sa rozhodol podeliť sa s vami o to, čo pre mňa bolo prvým dotykom s ethereum blochainom a SC. V tejto časti sa nezaobídeme bez aspoň základov programovania a tí pokročilejší, s rozbehnutým node.js envirnomentom na svojom pc si môžu svoj SC aj spustiť a hrať sa s ním. Ak nemáte nainštalovaný node.js nevadí, v tutoriále je zahrnuté rozbehnutie od samotných základov.
Poďme si v prvom rade ozrejmiť základné pojmy, samozrejme všetko v angličtine:

Public Key Cryptography – Ferko má svoj public key(verejný kľúč) a svoj private key(privátny kľúč). Ferko môže použiť svoj privátny kľúč pre vytvorenie digitálneho podpisu a Jožko, môže použiť Ferkov verejný kľúč na overenie že Ferkov podpis je naozaj vytvorený z Ferkovho privátneho kľúča. Keď vytvárame kryptopeňaženku či už pre Ethereum alebo Bitcoin, dlhá sekvencia znakov ako ‘0xld…5c’ čo je adresou peňaženky, je vlastne verejný kľúč. Služba akou je napríklad Coinbase, ukladá privátny kľúč automaticky. No ak nevyužívate podobnú službu, je extrémne dôležité mať svoje privátne kľúče zálohované, pretože ak ho raz stratíte, stratíte aj svoje prostriedky v kryptomene raz a navždy.

Peer-to-Peer Networking – Podobne ako BitTorrent, aj Ethereum funguje ako decentralizovaná sieť. To znamená, že na sieti nieje určený centralizovaný server, ktorý spracuváva požiadavky siete ale účastníci si ich spracuvávajú medzi sebou.

Blockchain – v skratke, globálna účtovná kniha, či databáza s históriou všetkých transakcií na sieti.

Ethereum Virtual Machine – odkazuje sa na blockchain, ktorý spúšťa smart contracty. V podstate je to jeden veľký globálny superpočítač.

Node – odkazuje na bod alebo entitu použitím ktorej môžete čítať a zapisovať na ethereum blockchain použitím Ethereum Virtual Machine. Výraz “Full Node” znamená že entita ma stiahnutý celý ethereum blockchain.

Miner – entita na sieti ktorá ťaží kryptomenu poskytnutím svojej výpočtovej sily.

Proof of Work – Dôkaz práce, čo dokazuje, že bolo vynaložené úsilie na priebeh hash funkcie resp. zapečatenie bloku.

Ether – alebo krátko ETH, ktorý netreba predstavovať.

Gas – Oddelená jednotka od ETH využívaná na platby za ukladanie informácií a spúšťanie smart contractov kde spustenie každej funkcie “stojí nejaký ten gas”.

DApp – Decentralizovaná aplikácia ktorá je v podstate(alebo by mala byť) zaobalený smart contract do pekného užívateľského prostredia(UI).

Vývojárske prostredie a rozbehanie potrebných frameworkov

V tomto momente ovládame základné pojmy s ktorými sa budeme stretávať aj v budúcich tutoriáloch a môžeme sa pustiť do nášho prvého smart contractu. V tomto tutoriále počítam ale s tým, že developer čítajúci tento tutoriál vyvíja na niektorej z distribúcii Linuxu alebo využíva macOS, pretože v tejto prvej časti sa budeme zameriavať čisto len na prácu v terminály.
Pokiaľ nemáte k dispozícii macOS alebo niektorú z distribúcií Linuxu, existuje lepšie riešenie ako inštalácia virtuálky. Odporúčam služby Amazonu – Amazon AWS kde si jednoducho založíte free konto, zvolíte si free virtuálny server na ktorom máte automaticky nainštalovaný Linux a pripojíte sa jednoducho cez SSH pripojenie v konzole. Ja využívam macOS, takže terminál mi je druhým domovom.

Začnime od úplných základov a to inštaláciou Homebrew, Git a node.js. Môžete ísť na oficiálne stránky alebo jednoducho kopírovať príkazy nižšie ktoré len vložíte do konzoly:

Začneme inštaláciou Homebrew čo je package manager pre macOS či Linux. Jednoducho otvoríme terminál a pastneme tam tento príkaz:

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

Po zbehnutí pokračujeme inštaláciou Git-u čo je distribuovaný systém riadenia revízií. Pod týmto názvom sa myslí, že software, ktorý vyvýjate sa dá ukladať a rozdeľovať do jednotlivých verzií, ktoré pomocou neho môžete spravovať. Keďže už máme nainštalovaný package manager Homebrew, ten nám pomôže nainštalovať všetko potrebné čo ku Git-u potrebujeme:

brew install git

Teraz sa posunieme k inštalácii node.js. Node.js je softwarový systém navrhnutý pre písanie vysokoškálovateľných internetových aplikácií písaných v jazyku Javascript. Jeho inštalácia zaberie minimálne 20 minút. Použijeme tento príkaz:

brew update && brew install -v node

Základ máme nainštalovaný, teraz sa môžeme pustiť do inštalácie toho podstatného a to je testovací ethereum blockchain “testrpc”.

Testovaciu sieť nainštalujeme príkazom:

npm install -g ethereumjs-testrpc

a po jej zbehnutí ju spustíme príkazom:

testrpc

kde by sa nám mala zobraziť táto obrazovka:

1_testrpc

Testrpc nám automaticky vytvorí niekoľko predpripravených accountov ktoré môžeme používať pri vývoji či testovaní.

Ďalšia pre nás podstatná vec je Truffle. Ako už som písal hore, Truffle predstavuje testovací a vývojový framework, ktorý zjednoduchšuje spúšťanie a testovanie smart contractov. Veľmi pomáha najmä pri procese kompilácie smart contractu, jeho migrácie na blockchain a testovaní pomocou truffle konzoly.

Inštaláciu spustíme príkazom:

npm install -g truffle

V tomto momente máme nainštalované a rozbehnuté všetko potrebné a môžeme začať so samotným vývojom nášho prvého smart contractu.

Začneme tým, že si spustíme testrpc a v druhom okne termínálu sa navygujeme do zložky kde chceme SC uložiť. Truffle nám už veľmi pomôže pri samotných začiatkoch kde nám nainštaluje do našej zložky základný balíček. Nainštalujeme ho príkazom:

truffle init

Truffle nám nainštaloval základné súbory s testovacími ktoré môžeme použiť pre inšpiráciu ale my si vytvoríme vlastný. Štruktúra ktorá sa nám zobrazí v editore by mala vyzerať takto:

2_atom_file_structure

Ja používam editor Atom. Je na vás aký použijete. V závyslosti od projektu striedam Atom a webStorm. V priloženom screenshote vidíme vyznačený súbor Accounts.sol. To je súbor, ktorý sme si “ručne” vytvorili v zložke “contracts” medzi ostatné SC.

Našou úlohou je teraz vytvoriť SC, ktorý bude vytvárať záznami o ľuďoch, resp. vytvárať accounty s informáciami ako meno, priezvisko a vek. Pre písanie SC sa využívajú rôzne jazyky, zasa v závislosti od projektu. Asi najvyužívanejším je jazyk Solidity s príponou .sol alebo napríklad Serpent, veľmi podobný jazyku Python s príponou .se. Schválne som vykradol už existujúci SC s trocha jednoduchšími funkciami len na ukladanie a zobrazovanie dát aby bol čo najlepšie použiteľný ako príklad aj pri vytváranií UI ktoré budeme vytvárať v budúcej časti tutoriálu.

Kým sa dostaneme k samotnému kódu, premýšľal som ako najefektívnejšie vysvetliť aký riadok kódu čo robí. Keby som písal kód po častiach a po častiach ich vysvetľoval, tak tento tutoriál by nebol tutoriálom ale čítaním na celý večer ktoré by nikto nerozlúštil, preto som sa rozhodol celý kód sem pastnúť naraz s tým, že každý riadok kódu sa budem snažiť čo najstručnejšie a najpochopiteľnejšie vysvetliť komentármi priamo v kóde.

pragma solidity ^0.4.13;

contract Accounts { //definovanie contractu, podobné ako definovanie class v javascripte
  //v tejto sekcii si definujeme premenné
  Account[] public account; //definovali sme si array s kľúčovým slovom "public" ktoré zabezpečí že premenná
  //je volateľná aj mimo contactu... ak by sme zadali kľúčové slovo "private", premenná by bola uzavretá len v rámci smart contractu

  struct Account { //tu sme si definovali objekt
    bytes32 firstName; //ku každému property objektu sme si definovali aj dátový typ
    bytes32 lastName; //čiže byte32 ukladá len znaky spolu dlhé max 32 bytov.
    uint age; //ukladá dátový typ integer
  }

  function addAccount(bytes32 _firstName, bytes32 _lastName, uint _age) returns (bool success) {
    //definovaná funkcia so vstupmi s definovanými dátovými typmi
    Account memory newAccount; //dáta označené "memory" odkazujú Ethereum Virtual Machine na
    //uloženie v dočasnom úložisku ktoré sa vymaže medzi externými volaniami funkcíí a hlavne je lacnejšie na použitý Gas

    newAccount.firstName = _firstName; //vstupy funkcie ukladáme do jednotlivých property objektu
    newAccount.lastName = _lastName;
    newAccount.age = _age;

    account.push(newAccount); //funckia push nám vloží objekt do array-u
    return true; //vráti nám hodnotu ktorú sme si definovali hore pri "returns"
  }

  function getAccounts() constant returns (bytes32[], bytes32[], uint[]) {
    //funkcia s definovanými výstupmi
    uint length = account.length;

    bytes32[] memory firstNames = new bytes32[](length); //predpripravené premenné do ktorých nasledujúci cyklus for bude vkladať dáta
    bytes32[] memory lastNames = new bytes32[](length);
    uint[] memory ages = new uint[](length);

    for (uint i = 0; i < account.length; i++) {
      //cyklus for prechádza Account z memory EVM, vkladá ich do nových premenných
      //aktuálneho objektu a vracia ich podľa hore definovaných výstupov
      Account memory currentAccount;
      currentAccount = account[i];

      firstNames[i] = currentAccount.firstName;
      lastNames[i] = currentAccount.lastName;
      ages[i] = currentAccount.age;

    }
    return (firstNames, lastNames, ages);
  }

}

Po skopírovaní alebo prepísaní kódu do svojho súboru Accounts.sol a pred jeho deploynutím musíme definovať aký súbor sa má deploynúť na sieť. Vojdeme do zložky “migrations” a otvoríme súbor “2_deploy_contracts.js”, kde requirneme súbor Accounts.sol a ostatok zakomentujeme alebo zmažeme. Súbor by mal vyzerať takto:

//var ConvertLib = artifacts.require("./ConvertLib.sol");
//var MetaCoin = artifacts.require("./MetaCoin.sol");
var Accounts = artifacts.require("./Accounts.sol");

module.exports = function(deployer) {
	//deployer.deploy(ConvertLib);
	//deployer.link(ConvertLib, MetaCoin);
	//deployer.deploy(MetaCoin);
	deployer.deploy(Accounts);
};

Po úpravách ktoré sme vykonali, prišiel čas náš SC premigrovať na sieť a spustiť. Uistime sa, že stále beží náš testrpc. V rovnakej zložke ako je náš projekt(v jej roote) spustíme postupne nasledujúce príkazi:

truffle deploy
truffle migrate
truffle console

Po zadaní “truffle console” by sa nám mala otvoriť konzola:

3_truffle_console

Ak deploy prebehol správne, po pozadaní:

4_truffle_console_deployed

mal by sa nám zobraziť strom funkcií:

5_truffle_console_deployed_tree

Ak ste sa dostali až sem, gratulujem, vyzerá to tak že základ máme zmáknutý a teraz prišiel čas otestovať naše funkcie. Mali by sme pridať na sieť account s menom, priezviskom a vekom. Zavoláme si teda v konzole funkciu do ktorej vložíme vstupné parametre tak ako sme si to definovali v SC:

6_truffle_console_addAccount

Po zavolaní funkcie by nám mala konzola vrátiť info o transakcii ako tu:

7_truffle_console_addAccount_output

Veľmi dôležité a podstatné je si uvedomiť, že na každý výpočet alebo vynaloženie výpočtovej sily sa spotrebúva Gas, preto každý SC musí byť napísaný čo najefektívnejšie bez zbytočného vytvárania premenných a celkovo “hovnokódu” pretože ak sa minie Gas, SC sa zastaví, inak by existoval a fungoval na sieti navždy.

Teraz keď sme si uložili dáta na sieť, môžeme ich funkciou getAccounts získať:

8_truffle_console_getAccount

Výstup v konsole by mal vyzerať takto:

9_truffle_console_getAccount_output

Prvý riadok je zahashované meno, druhý riadok je zahashované priezvisko a tretí riadok je obyčajný integer vek. Gratulujem, práve ste napísali váš prvý ethereum smart contract.

Na záver(schválne) tohto prvého dielu tutoriálu prikladám git clone k môjmu repozitáru na Githube kde si môžete stiahnúť zdrojové dáta:

https://github.com/OndroS/First-Smart-Contract-1.git

V budúcom diele si spoločne pripravíme UI rozhranie pre náš smart contract napojením na ReactJS a tak vytvoríme našu prvú DAppku.

Ak vás téma zaujala, určite si pozrite aj toto:

Kickstarter na steroidoch + Ethereum Blockchain = ICO

Related Posts