Dobrodošli u novi serijal o radu s Embark okruženjem. Pretpostavka je da imate osnovno znanje programiranja i da ste prošli barem neke od naših osnovnih članaka ili tehničkih vodiča, posebice uvod u Ethereum i možda izradu tombole na Ethereumu.


Embark je skup alata za razvijanje decentraliziranih aplikacija na Ethereum blockchainu. Služi kao alternativa za Truffle i dolazi s raznim dodacima kao što su automatska integracija s IPFSom i ENSom, okvir za web aplikaciju baziran na ReactJS-u, i drugo.

Embark je počeo s razvojem prije nekih 3 godine, a nedavno ga je preuzeo Status koji financira njegov razvoj i pospješuje rast Embark ekosustava.

U ovom ćemo vodiču naučiti kako početi s Embarkom te kako napraviti jednostavni pametni ugovor za vlastiti token.

Instalacija

Za svrhu ovog vodiča pretpostaviti ćemo da ste na *nix operativnom sustavu kao što je OS X ili neka verzija Linuxa. Ako niste, predlažemo da preuzmete Git Tools i time Git Bash koji to okruženje kvalitetno simulira, ili da pokrenete jednostavnu i praktičnu virtualnu mašinu koja će vam pružiti potpuno izolirano Linux okruženje. Najbolja opcija za to je Homestead Improved.

Preduvjeti za korištenje Embarka su da imate ažurnu verziju NodeJS-a, ažurnu verziju IPFSa i ažurnu verziju Getha (Ethereum Go klijenta). Zbog generalne slomljenosti NodeJS-a, predlažemo da koristite NVM alat koji dopušta laku izmjenu verzije NodeJS-a na istom sustavu. Pokrenite sljedeće naredbe da instalirate NVM i aktivirate najnoviju stabilnu verziju NodeJS-a:

curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash
nvm install --lts
nvm use --lts

Napomena: na Windows sustavu ne postoji službena verzija NVMa. Alternative su nvm-windows i nodist.

Upute za instalaciju IPFSa dostupne su ovdje.

Upute za instalaciju Getha dostupne su ovdje.

Nakon što instalirate sve potrebne alate, provjerite jesu li funkcionalni ispisom njihovih verzija. Sve verzije trebaju biti jednake ili veće od ovih na slici ispod.

Versions

Zatim preuzimamo Embark.

npm -g install embark

Nakon toga, u mapi u kojoj želimo započeti svoj projekt pokrećemo naredbu:

embark new tokentutorial
cd tokentutorial

Konačno, pokrenimo komandu embark run koja će pokrenuti Embark Dashboard.

Konfiguracija

U mapi config nalaze se konfiguracijske varijable za razne dijelove projekta. Ono što nama u ovom momentu treba je datoteka config/contracts.js u kojoj je definirano okruženje u kojem se pametni ugovori lansiraju na neki blockchain. Taj kod trenutno izgleda ovako:

“`js
module.exports = {
* // default applies to all environments*
* default: {*
* // Blockchain node to deploy the contracts*
* deployment: {*
* host: “localhost”, // Host of the blockchain node*
* port: 8545, // Port of the blockchain node*
* type: “rpc” // Type of connection (ws or rpc),*
* },*
* dappConnection: [*
* “$WEB3”, // uses pre existing web3 object if available (e.g in Mist)*
* “ws://localhost:8546”,*
* “http://localhost:8545”*
* ],*
* gas: “auto”,*
* contracts: {*
* // example:*
* //SimpleStorage: {*
* // args: [ 100 ]*
* //}*
* }*
* },*
};

// …
“`

Ukratko, ovo znači da standardno okruženje za pokretanje naše decentralizirane aplikacije i njenih pametnih ugovora treba biti na localhost serveru, port 8545 – to odgovara Ethereum Geth čvoru kojeg pokreće Ember prilikom ember run naredbe.

dappConnection određuje na koji način da se web aplikacija povezuje s blockchainom prilikom pokretanja – preferira web3 objekt kojeg nudi MetaMask ili Status, a ukoliko ta veza nije dostupna (MetaMask nije instaliran ili aplikacija ne nudi Web3), prelazi na direktni pristup na čvor – prvo preko websocketa, zatim preko običnih HTTP poziva kroz Emberovu verziju Web3.0. Ovaj dio obično nije potrebno mijenjati.

gas govori našoj aplikaciji koliko Gas-a da maksimalno potroši za pokretanje nekog ugovora. auto vrijednost sama procjenjuje potrebnu količinu i ta vrijednost je najbolja opcija za lokalno razvijanje gdje se ne radi o pravom Etheru.

Konačno, tu je i najbitniji dio – dio koji određuje koje pametne ugovore naša aplikacija pošalje na blockchain. Bez ovog dijela, ni jedan ugovor koji napišemo neće završiti na blockchainu. Pretpostavimo da ćemo izgraditi ugovor koji ćemo nazvati BitfallsToken i izmjenimo ovaj dio.

contracts: {
  BitfallsToken: {}
}

Embark će sada pratiti promjene među datotekama našeg projekta i ukoliko detektira izmjene u datoteci contracts/BitfallsToken.sol (koju ćemo tek kreirati), automatski će je izgraditi i staviti na blockchain. U ovom slučaju, budući da BitfallsToken.sol još ne postoji, Embark javlja grešku.

Embark error

Ostale mogućnosti konfiguracije proučite u službenoj dokumentaciji.

Krenimo sada u izgradnju tokena.

Dashboard

Embark dashboard je pomoćni alat koji će pratiti promjene u datotekama projekta i automatski ih ponovno kompajlirati po potrebi, kao što smo vidjeli gore. Primjerice, ako dodamo novi BitfallsToken.sol pametni ugovor, ili promijenimo konfiguraciju u embark.json tako da se sada umjesto jedne JavaScript datoteke spajaju dvije u jednu, Embark to automatski prepoznaje i ponovno gradi naš projekt na virtualnom blockchainu koji vrti u pozadini.

Primjerice, ako u mapu contracts dodamo datoteku BitfallsToken.sol s sljedećim sadržajem:

pragma solidity ^0.4.25;

contract BitfallsToken {
    constructor() public {
    
    }
}

… primjetiti ćete da je Embark dashboard na to reagirao, ponovno izgradio našu aplikaciju, i ispisao adresu na kojoj je pokrenuo taj pametni ugovor.

Deploy

Dodavanje Drugih Paketa

Da ne razvijamo token iz nule, možemo iskoristiti već postojeće i dobro testirane šablone drugih, daleko boljih programera. Koristiti ćemo OpenZeppelin ugovore koje ćemo “proširiti” za naš slučaj.

Da dodamo OpenZeppelin u naš projekt, pokrećemo sljedeću naredbu:

npm install openzeppelin-solidity@next

Ti pametni ugovori sada postaju dostupni u mapi node_modules, a da ih koristimo u našim ugovorima, potrebno je napraviti import. Na vrh BitfallsToken.sol datoteke a ispod pragma linije dodajemo:

import "openzeppelin-solidity/contracts/token/ERC20/ERC20.sol";

Odmah nakon spremanja datoteke s CMD/CTRL+S vidjeti ćemo da Embark Dashboard primjećuje promjene i gradi projekt ispočetka, šaljući ugovore koje ovaj import podrazumijeva na mrežu.

Import deploy

Ugovor ERC20.sol koji importamo i sam ima više import deklaracija: SafeMath i IERC20.sol, od kojih je potonji samo sučelje (interface) – tip ugovora koji se ne šalje na mrežu, već koristi samo za definiciju funkcija koje neki ugovor mora imati.

Npr.: sučelje IERC20 definira da token koji se želi proglasiti ERC20 kompatibilnim ima funkciju transfer. Ako ta funkcija ne postoji u tokenu koji tvrdi da je ERC20 token, tada to nije ERC20 token. To je korisno kod automatskih listanja tokena na nekim burzama – ako neka burza zna da je neki token ERC20, odmah znaju i koje funkcije ima, pa time mogu vrlo lako dodati taj token među postojeće bez mnogo preinaka u kodu.

Da bismo naš token učinili “nasljednikom” tog ERC20.sol ugovora, mijenjamo liniju contract BitfallsToken { u:

contract BitfallsToken is ERC20 {

is X ovdje znači “nasljeđuje sve funkcije iz X, i može imati dodatne funkcije”.

Nakon spremanja promjena, Embark ih prepoznaje i gradi naš projekt. Ugovore koji su već lansirani ne pokreće ponovno, već prepoznaje da nisu mijenjani. BitfallsToken ima promjene, pa se ponovno deploya na novu adresu vidljivu na vrhu dashboarda.

Razvoj Tokena

Sada imamo solidan okvir za naš token. Personalizirajmo ga.

Prvo, potrebno je dodati mu standardne definicije: oznaku, ukupni iznos tokena, ime. Mijenjamo kod BitfallsToken.sol datoteke u sljedeći:

pragma solidity ^0.4.25;

import "openzeppelin-solidity/contracts/token/ERC20/ERC20.sol";

contract BitfallsToken is ERC20 {
    string public name = "Bitfalls Token";
    string public symbol = "MEH";
    uint256 public decimals = 18;
    
    constructor() public {
    
    }
}

Sada će naš token nakon pokretanja biti nazvan “Bitfalls Token”, imati će oznaku MEH na mjenjačnicama i burzama te će imati 18 decimala baš kao i ether.

No, ovo nam ništa ne koristi – token se nikome ne šalje, već samo stoji na mreži, lebdi u eteru. Dodajmo mu constructor:

    constructor() public {
        _mint(msg.sender, 100 * 10**6 * 10**decimals);
    }

Constructori su funkcije koje se automatski pokreću prilikom prvog pokretanja nekog pametnog ugovora. Koriste se za podešavanje početnog stanja ugovora poput početnih bilanci računa, vlasnika ugovora ili aplikacije, distribucije tokena, vremenskog ograničenja ICOa, i drugo. U ovom slučaju pozivamo ugrađenu internu funkciju _mint koja dolazi iz ERC20.sol ugovora kojeg smo prije importali.

Ona prima dva argumenta – adresu i iznos, te na zadanu adresu pripisuje iznos, istovremeno povećavajući ukupnu zalihu tih tokena.

Ono što će ovaj constructor učiniti je sljedeće: na adresu koja ovaj ugovor pošalje na blockchain (msg.sender) poslati će svih 100 milijuna Bitfalls tokena.

No, koja je to adresa? Tko je pošiljatelj tog pametnog ugovora?

onDeploy

Kad pokrenete embark run, on pokreće prije instalirani geth kao privatni Ethereum čvor na koji će naši ugovori biti poslani.

Taj čvor ima svoje Ethereum račune s kojih pokreće komande, pa će tako msg.sender iz gornjeg dijela biti neka nasumična adresa koju Geth sam generira. No, mi kao korisnici nemamo pristup tom računu, pa nam činjenica da su svi tokeni poslani baš na njega ne pomaže – zapravo, naši su tokeni neupotrebljivi jer ne postoji način da im pristupimo preko tog “tuđeg” računa.

Ovdje nam u pomoć stiže onDeploy okidač. Prilikom deploymenta, tj. slanja ugovora na mrežu, embark prolazi kroz određene okidače: prvo onDeploy kod svakog ugovora individualno, pa afterDeploy nakon svih. onDeploy se definira u config/contracts.js, kao atribut ugovora o kojem se radi.

Definirajmo onDeploy poziv koji šalje sve tokene s originalne adrese na neku koju mi kontroliramo – primjerice neka koju za nas generira MetaMask. U mom slučaju to je adresa 0x5666c33bb922F97B6721D3f932dfD9350C933a6F.

    contracts: {
      BitfallsToken: {
        "onDeploy": ["BitfallsToken.methods.transfer('0x5666c33bb922F97B6721D3f932dfD9350C933a6F', \"100000000000000000000000000\").send()"]
      },
    }

Ovo doslovno znači “Prilikom deploymenta Bitfalls Tokena od dostupnih metoda na token ugovoru odaberi metodu transfer i preko nje pošalji na adresu 0x5666... 100 milijuna tokena s 18 decimala”.

Navodnici s kosom crtom (\") oko velikog broja tokena potrebni su jer je to prevelik broj da ga JavaScript prepozna kao broj, pa broj trebamo predstaviti kao string umjesto broja.

Još nam je jedan problem preostao – naš 0x5666c33bb922F97B6721D3f932dfD9350C933a6F novčanik nema ethera koji mu je potreban za slanje tokena na druge adrese. Za vrijeme razvojnog stadija naših pametnih ugovora lako je definirati količinu ethera koju da pripišemo pojedinim adresama. Potreban nam je privatni ključ adrese na koju želimo staviti ether – u MetaMasku to se lako dobije klikom na “Details” pa “Export Private Key”.

Napomena: Budite pažljivi da ne koristite privatni ključ adrese koju inače koristite – privatni ključ na testnetu ili privatnom blockchainu otključava i istu adresu na glavnom lancu.

Nakon što imamo privatni ključ, u datoteci config/contracts.js definiramo koliko ethera mu želimo dati:

// ...
  deployment: {
      host: "localhost", // Host of the blockchain node
      port: 8545, // Port of the blockchain node
      type: "rpc" // Type of connection (ws or rpc),
      // Accounts to use instead of the default account to populate your wallet
      ,accounts: [
         {
          privateKey: "72F515AD44...9C0",
          balance: "5 ether"  // You can set the balance of the account in the dev environment
         }

Konačno, pokrenimo Embark Run ispočetka (možete ga zaustaviti pritiskom na CTRL+C).

Ako sada pogledamo stanje našeg Ethereum računa, vidjeti ćemo 5 ethera.

5 ether
5 ether

Dodajmo mu naš Bitfalls token klikom na Add Token i unosom adrese tokena. Adresu možete naći u Embark Dashboardu, ali i u datoteci chains.js.

Add token
Add token

Nakon dodavanja, stanje našeg računa biti će 5 ethera, i 100 milijuna Bitfalls MEH tokena.

Token + ether
Token + ether

Ako pokušamo poslati tokene na drugu adresu, sve radi kako treba:

Send token
Send token

Zaključak

Kao što vidite, razviti token pomoću Embarka je izuzetno jednostavno. Proces razvoja tokena je identičan onome u drugim razvojnim okruženjima, s dodatnom prednosti Embark Dashboarda i ostalih pomoćnih alata koji nam dopuštaju da se fokusiramo na razvoj, a ne na podešavanje sustava.

U sljedećem članku, osim dodavanja posebnih funkcija na naš token usredotočiti ćemo se na neizostavni dio razvoja pametnih ugovora: testiranje.

LEAVE A REPLY

Please enter your comment!
Please enter your name here