Blockchain: aké PoC by sme mali vybudovať?

Vaše oči sa boja a ruky vás svrbia!

V predchádzajúcich článkoch sme sa zaoberali technológiami, na ktorých sú blockchainy postavené (Čo by sme mali vybudovať blockchain?) a prípady, ktoré možno s ich pomocou realizovať (Prečo by sme mali stavať prípad?). Je čas pracovať rukami! Na implementáciu pilotov a PoC (Proof of Concept) radšej používam cloudy, pretože... sú prístupné odkiaľkoľvek na svete a často nie je potrebné strácať čas únavnou inštaláciou prostredia, pretože Existujú prednastavené konfigurácie. Urobme si teda niečo jednoduché, napríklad sieť na prenos coinov medzi účastníkmi a nazvime to skromne Bitcoin. Na to použijeme cloud IBM a univerzálny blockchain Hyperledger Fabric. Po prvé, poďme zistiť, prečo sa Hyperledger Fabric nazýva univerzálny blockchain?

Blockchain: aké PoC by sme mali vybudovať?

Hyperledger Fabric – univerzálny blockchain

Všeobecne povedané, univerzálny informačný systém je:

  • Sada serverov a softvérového jadra, ktoré vykonáva obchodnú logiku;
  • Rozhrania pre interakciu so systémom;
  • Nástroje na registráciu, autentifikáciu a autorizáciu zariadení/ľudí;
  • Databáza uchovávajúca prevádzkové a archívne údaje:

Blockchain: aké PoC by sme mali vybudovať?

Oficiálnu verziu toho, čo je Hyperledger Fabric, si môžete prečítať na Online, a v skratke Hyperledger Fabric je platforma s otvoreným zdrojom, ktorá vám umožňuje budovať súkromné ​​blockchainy a vykonávať ľubovoľné inteligentné zmluvy napísané v programovacích jazykoch JS a Go. Pozrime sa podrobne na architektúru Hyperledger Fabric a presvedčte sa, že ide o univerzálny systém, ktorý má špecifiká len na ukladanie a zaznamenávanie dát. Špecifikom je, že dáta, tak ako vo všetkých blockchainoch, sú uložené v blokoch, ktoré sú umiestnené na blockchaine len v prípade, že účastníci dosiahnu konsenzus a po zaznamenaní dáta nie je možné potichu opraviť alebo vymazať.

Hyperledger Fabric Architecture

Diagram zobrazuje architektúru Hyperledger Fabric:

Blockchain: aké PoC by sme mali vybudovať?

Organizácia — organizácie obsahujú rovesníkov, t.j. blockchain existuje vďaka podpore organizácií. Súčasťou jedného kanála môžu byť rôzne organizácie.

kanál — logická štruktúra, ktorá spája rovesníkov do skupín, t.j. blockchain je špecifikovaný. Hyperledger Fabric dokáže súčasne spracovať viacero blockchainov s rôznou obchodnou logikou.

Poskytovateľ členských služieb (MSP) je CA (Certifikačná autorita) pre vydávanie identity a prideľovanie rolí. Ak chcete vytvoriť uzol, musíte spolupracovať s MSP.

Peer uzly — overovať transakcie, ukladať blockchain, vykonávať inteligentné zmluvy a komunikovať s aplikáciami. Rovesníci majú preukaz totožnosti (digitálny certifikát), ktorý vydáva MsP. Na rozdiel od siete Bitcoin alebo Etherium, kde majú všetky uzly rovnaké práva, uzly v Hyperledger Fabric hrajú rôzne úlohy:

  • Peer možno podporujúci rovesník (EP) a vykonávať inteligentné zmluvy.
  • Zaväzujúci rovesník (CP) - uložte iba údaje do blockchainu a aktualizujte „Svetový stav“.
  • Anchor Peer (AP) – ak sa na blockchaine zúčastňuje niekoľko organizácií, na komunikáciu medzi nimi sa používajú kotevní rovesníci. Každá organizácia musí mať jedného alebo viacerých kotviacich kolegov. Pomocou AP môže každý rovesník v organizácii získať informácie o všetkých rovesníkoch v iných organizáciách. Používa sa na synchronizáciu informácií medzi AP klebetný protokol.
  • Líder Peer — ak má organizácia niekoľko partnerov, potom iba vedúci partnera dostane bloky od objednávkovej služby a dá ich ostatným partnerom. Líder môže byť špecifikovaný staticky alebo dynamicky vybraný partnermi v organizácii. Gossip protokol sa používa aj na synchronizáciu informácií o lídroch.

Aktíva — entity, ktoré majú hodnotu a sú uložené na blockchaine. Konkrétnejšie ide o údaje kľúč – hodnota vo formáte JSON. Práve tieto údaje sú zaznamenané v Blockchaine. Majú históriu, ktorá je uložená v blockchaine, a aktuálny stav, ktorý je uložený v databáze “World state”. Dátové štruktúry sa plnia ľubovoľne v závislosti od obchodných úloh. Neexistujú žiadne povinné polia, jediným odporúčaním je, že aktíva musia mať vlastníka a musia byť hodnotné.

Hlavná kniha — pozostáva z Blockchainu a databázy stavu Word, ktorá uchováva aktuálny stav aktív. Svetový štát používa LevelDB alebo CouchDB.

Inteligentná zmluva — pomocou inteligentných zmlúv sa implementuje obchodná logika systému. V Hyperledger Fabric sa inteligentné zmluvy nazývajú reťazový kód. Pomocou reťazového kódu sú špecifikované aktíva a transakcie nad nimi. Z technického hľadiska sú smart kontrakty softvérové ​​moduly implementované v programovacích jazykoch JS alebo Go.

Zásady schvaľovania — pre každý reťazový kód môžete nastaviť politiku, koľko potvrdení pre transakciu sa má očakávať a od koho. Ak toto pravidlo nie je nastavené, predvolená hodnota je: „transakciu musí potvrdiť ktorýkoľvek člen akejkoľvek organizácie v kanáli.“ Príklady pravidiel:

  • Transakciu musí schváliť ktorýkoľvek správca organizácie;
  • Musí byť potvrdené ktorýmkoľvek členom alebo klientom organizácie;
  • Musí byť potvrdené akoukoľvek partnerskou organizáciou.

Objednávková služba — zbalí transakcie do blokov a odošle ich partnerom v kanáli. Garantuje doručenie správ všetkým partnerom v sieti. Používa sa pre priemyselné systémy Sprostredkovateľ správ Kafka, na vývoj a testovanie sólo.

CallFlow

Blockchain: aké PoC by sme mali vybudovať?

  • Aplikácia komunikuje s Hyperledger Fabric pomocou Go, Node.js alebo Java SDK;
  • Klient vytvorí TX transakciu a odošle ju podporným partnerom;
  • Peer overí podpis klienta, dokončí transakciu a pošle potvrdzujúci podpis späť klientovi. Reťazový kód sa vykoná iba na podpornom partnerovi a výsledok jeho vykonania sa odošle všetkým partnerom. Tento algoritmus práce sa nazýva konsenzus PBFT (Practical Byzantine Fault Tolerant). Líši sa od klasický BFT skutočnosť, že správa je odoslaná a potvrdenie sa očakáva nie od všetkých účastníkov, ale iba od určitej skupiny;
  • Potom, čo klient dostane počet odpovedí zodpovedajúci politike schvaľovania, odošle transakciu službe Objednávanie;
  • Služba Objednávanie vygeneruje blok a odošle ho všetkým zaväzujúcim partnerom. Objednávková služba zaisťuje sekvenčnú evidenciu blokov, čím odpadá tzv. ledger fork (pozri časť "Vidlice");
  • Partneri dostanú blok, znova skontrolujú politiku schvaľovania, zapíšu blok do blockchainu a zmenia stav v DB „World state“.

Tie. Výsledkom je rozdelenie rolí medzi uzlami. To zaisťuje, že blockchain je škálovateľný a bezpečný:

  • Inteligentné zmluvy (reťazový kód) vykonávajú schvaľovanie rovesníkov. Tým je zabezpečená dôvernosť inteligentných zmlúv, pretože neukladajú ho všetci účastníci, ale iba potvrdzujúci kolegovia.
  • Objednávka by mala fungovať rýchlo. Toto je zabezpečené tým, že Ordering tvorí iba blok a posiela ho pevne stanovenej skupine lídrov.
  • Poverení kolegovia iba ukladajú blockchain – môže ich byť veľa a nevyžadujú veľa energie a okamžitú prevádzku.

Viac podrobností o architektonických riešeniach Hyperledger Fabric a prečo to funguje tak a nie inak nájdete tu: Počiatky architektúry alebo tu: Hyperledger Fabric: Distribuovaný operačný systém pre povolené blockchainy.

Hyperledger Fabric je teda skutočne univerzálny systém, s ktorým môžete:

  • Implementujte ľubovoľnú obchodnú logiku pomocou mechanizmu inteligentných zmlúv;
  • Zaznamenávajte a prijímajte dáta z blockchainovej databázy vo formáte JSON;
  • Udeľte a overte prístup k API pomocou certifikačnej autority.

Teraz, keď už trochu rozumieme špecifikám Hyperledger Fabric, urobme konečne niečo užitočné!

Nasadenie blockchainu

Vyhlásenie o probléme

Úlohou je implementovať sieť Citcoin s nasledujúcimi funkciami: vytvorenie účtu, získanie zostatku, dobitie účtu, prevod mincí z jedného účtu na druhý. Nakreslíme si objektový model, ktorý ďalej implementujeme do smart kontraktu. Takže budeme mať účty, ktoré sú identifikované menami a obsahujú zostatok a zoznam účtov. Účty a zoznam účtov sú z hľadiska aktív Hyperledger Fabric. Podľa toho majú históriu a súčasný stav. Pokúsim sa to nakresliť jasne:

Blockchain: aké PoC by sme mali vybudovať?

Najvyššie čísla sú aktuálny stav, ktorý je uložený v databáze “World state”. Pod nimi sú obrázky zobrazujúce históriu, ktorá je uložená v blockchaine. Aktuálny stav majetku sa mení transakciami. Majetok sa mení len ako celok, takže v dôsledku transakcie sa vytvorí nový objekt a aktuálna hodnota majetku sa dostane do histórie.

IBM Cloud

Vytvoríme si účet v IBM cloud. Ak chcete používať blockchainovú platformu, musíte ju upgradovať na Pay-As-You-Go. Tento proces nemusí byť rýchly, pretože... IBM si vyžiada dodatočné informácie a manuálne ich overí. Pozitívne môžem povedať, že IBM má dobré školiace materiály, ktoré vám umožňujú nasadiť Hyperledger Fabric v ich cloude. Páčila sa mi nasledujúca séria článkov a príkladov:

Nasledujú snímky obrazovky platformy IBM Blockchain. Toto nie je návod, ako vytvoriť blockchain, ale jednoducho ukážka rozsahu úlohy. Takže pre naše účely vytvárame jednu organizáciu:

Blockchain: aké PoC by sme mali vybudovať?

Vytvárame v ňom uzly: Orderer CA, Org1 CA, Orderer Peer:

Blockchain: aké PoC by sme mali vybudovať?

Vytvárame používateľov:

Blockchain: aké PoC by sme mali vybudovať?

Vytvorte kanál a nazvite ho citcoin:

Blockchain: aké PoC by sme mali vybudovať?

Kanál je v podstate blockchain, takže začína blokom nula (blok Genesis):

Blockchain: aké PoC by sme mali vybudovať?

Spísanie inteligentnej zmluvy

/*
 * Citcoin smart-contract v1.5 for Hyperledger Fabric
 * (c) Alexey Sushkov, 2019
 */
 
'use strict';
 
const { Contract } = require('fabric-contract-api');
const maxAccounts = 5;
 
class CitcoinEvents extends Contract {
 
    async instantiate(ctx) {
        console.info('instantiate');
        let emptyList = [];
        await ctx.stub.putState('accounts', Buffer.from(JSON.stringify(emptyList)));
    }
    // Get all accounts
    async GetAccounts(ctx) {
        // Get account list:
        let accounts = '{}'
        let accountsData = await ctx.stub.getState('accounts');
        if (accountsData) {
            accounts = JSON.parse(accountsData.toString());
        } else {
            throw new Error('accounts not found');
        }
        return accountsData.toString()
    }
     // add a account object to the blockchain state identifited by their name
    async AddAccount(ctx, name, balance) {
        // this is account data:
        let account = {
            name: name,
            balance: Number(balance),       
            type: 'account',
        };
        // create account:
        await ctx.stub.putState(name, Buffer.from(JSON.stringify(account)));
 
        // Add account to list:
        let accountsData = await ctx.stub.getState('accounts');
        if (accountsData) {
            let accounts = JSON.parse(accountsData.toString());
            if (accounts.length < maxAccounts)
            {
                accounts.push(name);
                await ctx.stub.putState('accounts', Buffer.from(JSON.stringify(accounts)));
            } else {
                throw new Error('Max accounts number reached');
            }
        } else {
            throw new Error('accounts not found');
        }
        // return  object
        return JSON.stringify(account);
    }
    // Sends money from Account to Account
    async SendFrom(ctx, fromAccount, toAccount, value) {
        // get Account from
        let fromData = await ctx.stub.getState(fromAccount);
        let from;
        if (fromData) {
            from = JSON.parse(fromData.toString());
            if (from.type !== 'account') {
                throw new Error('wrong from type');
            }   
        } else {
            throw new Error('Accout from not found');
        }
        // get Account to
        let toData = await ctx.stub.getState(toAccount);
        let to;
        if (toData) {
            to = JSON.parse(toData.toString());
            if (to.type !== 'account') {
                throw new Error('wrong to type');
            }  
        } else {
            throw new Error('Accout to not found');
        }
 
        // update the balances
        if ((from.balance - Number(value)) >= 0 ) {
            from.balance -= Number(value);
            to.balance += Number(value);
        } else {
            throw new Error('From Account: not enought balance');          
        }
 
        await ctx.stub.putState(from.name, Buffer.from(JSON.stringify(from)));
        await ctx.stub.putState(to.name, Buffer.from(JSON.stringify(to)));
                 
        // define and set Event
        let Event = {
            type: "SendFrom",
            from: from.name,
            to: to.name,
            balanceFrom: from.balance,
            balanceTo: to.balance,
            value: value
        };
        await ctx.stub.setEvent('SendFrom', Buffer.from(JSON.stringify(Event)));
 
        // return to object
        return JSON.stringify(from);
    }
 
    // get the state from key
    async GetState(ctx, key) {
        let data = await ctx.stub.getState(key);
        let jsonData = JSON.parse(data.toString());
        return JSON.stringify(jsonData);
    }
    // GetBalance   
    async GetBalance(ctx, accountName) {
        let data = await ctx.stub.getState(accountName);
        let jsonData = JSON.parse(data.toString());
        return JSON.stringify(jsonData);
    }
     
    // Refill own balance
    async RefillBalance(ctx, toAccount, value) {
        // get Account to
        let toData = await ctx.stub.getState(toAccount);
        let to;
        if (toData) {
            to = JSON.parse(toData.toString());
            if (to.type !== 'account') {
                throw new Error('wrong to type');
            }  
        } else {
            throw new Error('Accout to not found');
        }
 
        // update the balance
        to.balance += Number(value);
        await ctx.stub.putState(to.name, Buffer.from(JSON.stringify(to)));
                 
        // define and set Event
        let Event = {
            type: "RefillBalance",
            to: to.name,
            balanceTo: to.balance,
            value: value
        };
        await ctx.stub.setEvent('RefillBalance', Buffer.from(JSON.stringify(Event)));
 
        // return to object
        return JSON.stringify(from);
    }
}
module.exports = CitcoinEvents;

Intuitívne by tu malo byť všetko jasné:

  • Existuje niekoľko funkcií (AddAccount, GetAccounts, SendFrom, GetBalance, RefillBalance), ktoré bude demo program volať pomocou Hyperledger Fabric API.
  • Funkcie SendFrom a RefillBalance generujú udalosti, ktoré demo program dostane.
  • Funkcia inštancie sa volá raz, keď sa vytvorí inštancia inteligentnej zmluvy. V skutočnosti sa volá nielen raz, ale vždy, keď sa zmení verzia inteligentnej zmluvy. Preto inicializácia zoznamu s prázdnym poľom je zlý nápad, pretože Teraz, keď zmeníme verziu smart kontraktu, stratíme aktuálny zoznam. Ale to je v poriadku, len sa učím).
  • Účty a zoznam účtov sú dátové štruktúry JSON. JS sa používa na manipuláciu s údajmi.
  • Aktuálnu hodnotu aktíva môžete získať pomocou volania funkcie getState a aktualizovať ju pomocou putState.
  • Pri vytváraní Účtu sa volá funkcia AddAccount, pri ktorej sa porovnáva maximálny počet účtov v blockchaine (maxAccounts = 5). A tu je zásek (všimli ste si?), ktorý vedie k nekonečnému zvyšovaniu počtu účtov. Takýmto chybám sa treba vyvarovať)

Ďalej načítame inteligentnú zmluvu do kanála a vytvoríme jej inštanciu:

Blockchain: aké PoC by sme mali vybudovať?

Pozrime sa na transakciu inštalácie Smart Contract:

Blockchain: aké PoC by sme mali vybudovať?

Pozrime sa na podrobnosti o našom kanáli:

Blockchain: aké PoC by sme mali vybudovať?

Výsledkom je nasledujúci diagram blockchainovej siete v cloude IBM. Diagram tiež ukazuje demo program spustený v cloude Amazon na virtuálnom serveri (viac o ňom v ďalšej časti):

Blockchain: aké PoC by sme mali vybudovať?

Vytvorenie GUI pre volania Hyperledger Fabric API

Hyperledger Fabric má API, ktoré možno použiť na:

  • Vytvoriť kanál;
  • Pripojenie typu peer to channel;
  • Inštalácia a inštancia inteligentných zmlúv v kanáli;
  • Volacie transakcie;
  • Vyžiadajte si informácie o blockchaine.

Vývoj aplikácií

V našom demo programe budeme API používať iba na volanie transakcií a vyžiadanie informácií, pretože Zvyšné kroky sme už dokončili pomocou platformy IBM blockchain. Píšeme GUI pomocou štandardného technologického zásobníka: Express.js + Vue.js + Node.js. O tom, ako začať s tvorbou moderných webových aplikácií, môžete napísať samostatný článok. Tu nechám odkaz na sériu prednášok, ktoré sa mi páčili najviac: Webová aplikácia Full Stack pomocou Vue.js a Express.js. Výsledkom je aplikácia klient-server so známym grafickým rozhraním v štýle Material Design od Google. REST API medzi klientom a serverom pozostáva z niekoľkých volaní:

  • HyperledgerDemo/v1/init - inicializujte blockchain;
  • HyperledgerDemo/v1/accounts/list — získajte zoznam všetkých účtov;
  • HyperledgerDemo/v1/account?name=Bob&balance=100 — vytvorte účet Bob;
  • HyperledgerDemo/v1/info?account=Bob — získajte informácie o účte Bob;
  • HyperledgerDemo/v1/transaction?from=Bob&to=Alice&volume=2 - preneste dve mince od Boba k Alici;
  • HyperledgerDemo/v1/disconnect – zatvorte spojenie s blockchainom.

Popis rozhrania API s príkladmi Webová stránka poštára - známy program na testovanie HTTP API.

Demo aplikácia v cloude Amazon

Nahral som aplikáciu na Amazon, pretože... IBM stále nedokázalo upgradovať môj účet a umožniť mi vytvárať virtuálne servery. Ako pridať čerešňu do domény: www.citcoin.info. Server nechám chvíľu zapnutý a potom ho vypnem, pretože... centy na prenájom kvapkajú a citcoiny ešte nie sú kótované na burze) Do článku prikladám screenshoty dema, aby bola jasná logika práce. Demo aplikácia môže:

  • Inicializujte blockchain;
  • Vytvorte si účet (teraz však nemôžete vytvoriť nový účet, pretože v blockchaine bol dosiahnutý maximálny počet účtov uvedený v inteligentnej zmluve);
  • Získajte zoznam účtov;
  • Prenášajte mince citcoinov medzi Alicou, Bobom a Alexom;
  • Prijímať udalosti (teraz však neexistuje spôsob, ako udalosti zobraziť, takže pre zjednodušenie rozhranie hovorí, že udalosti nie sú podporované);
  • Zaznamenať akcie.

Najprv inicializujeme blockchain:

Blockchain: aké PoC by sme mali vybudovať?

Ďalej si vytvoríme účet, nestrácajte čas so zostatkom:

Blockchain: aké PoC by sme mali vybudovať?

Získame zoznam všetkých dostupných účtov:

Blockchain: aké PoC by sme mali vybudovať?

Vyberieme odosielateľa a príjemcu a získame ich zostatky. Ak sú odosielateľ a príjemca rovnakí, jeho účet sa doplní:

Blockchain: aké PoC by sme mali vybudovať?

V denníku sledujeme vykonávanie transakcií:

Blockchain: aké PoC by sme mali vybudovať?

V skutočnosti je to všetko s demo programom. Nižšie môžete vidieť našu transakciu v blockchaine:

Blockchain: aké PoC by sme mali vybudovať?

A všeobecný zoznam transakcií:

Blockchain: aké PoC by sme mali vybudovať?

Týmto sme úspešne dokončili implementáciu PoC na vytvorenie siete Citcoin. Čo ešte treba urobiť, aby sa Citcoin stal plnohodnotnou sieťou na prevod coinov? Veľmi malý:

  • Vo fáze vytvárania účtu implementujte generovanie súkromného / verejného kľúča. Súkromný kľúč musí byť uložený u používateľa účtu, verejný kľúč musí byť uložený v blockchaine.
  • Uskutočnite prevod mincí, v ktorom sa na identifikáciu používateľa použije namiesto mena verejný kľúč.
  • Šifrujte transakcie smerujúce od používateľa na server pomocou jeho súkromného kľúča.

Záver

Implementovali sme sieť Citcoin s nasledujúcimi funkciami: pridanie účtu, získanie zostatku, dobitie účtu, prevod mincí z jedného účtu na druhý. Čo nás teda stálo vytvorenie PoC?

  • Musíte študovať blockchain vo všeobecnosti a Hyperledger Fabric konkrétne;
  • Naučte sa používať cloudy IBM alebo Amazon;
  • Naučte sa programovací jazyk JS a nejaký webový rámec;
  • Ak je potrebné niektoré dáta uložiť nie do blockchainu, ale do samostatnej databázy, tak sa naučte integrovať napríklad s PostgreSQL;
  • A v neposlednom rade - v modernom svete nemôžete žiť bez znalosti Linuxu!)

Samozrejme, nie je to žiadna veľká veda, ale budete musieť tvrdo pracovať!

Zdroje na GitHub

Zdroje uvedené GitHub. Stručný popis úložiska:
Katalóg "server» — Server Node.js
Katalóg "zákazník» — Klient Node.js
Katalóg "blockchain"(hodnoty parametrov a kľúče, samozrejme, sú nefunkčné a sú uvedené len ako príklad):

  • kontrakt — zdrojový kód inteligentnej zmluvy
  • peňaženka — užívateľské kľúče na používanie Hyperledger Fabric API.
  • *.cds – zostavené verzie smart kontraktov
  • Súbory *.json – príklady konfiguračných súborov na používanie Hyperledger Fabric API

Je to len začiatok!

Zdroj: hab.com

Pridať komentár