Blockchain: kaj naj zgradimo PoC?

Oči se bojijo, roke pa srbijo!

V prejšnjih člankih smo se ukvarjali s tehnologijami, na katerih so zgrajene verige blokov (Kaj naj zgradimo blockchain?) in primeri, ki jih je mogoče izvesti z njihovo pomočjo (Koliko nas stane izdelava primera?). Čas je za delo z rokami! Za izvedbo pilotov in PoC (Proof of Concept) najraje uporabljam oblake, ker. imajo dostop od kjer koli na svetu in pogosto ni treba porabiti časa za dolgočasno namestitev okolja, ker. Obstajajo prednastavljene konfiguracije. Torej, naredimo nekaj preprostega, kot je omrežje za prenos kovancev med udeleženci in ga skromno imenujemo Citcoin. Za to bomo uporabili IBM-ov oblak in univerzalno verigo blokov Hyperledger Fabric. Najprej ugotovimo, zakaj se Hyperledger Fabric imenuje univerzalna veriga blokov?

Blockchain: kaj naj zgradimo PoC?

Hyperledger Fabric – univerzalna veriga blokov

Na splošno je univerzalni informacijski sistem:

  • Nabor strežnikov in programskega jedra, ki izvaja poslovno logiko;
  • Vmesniki za interakcijo s sistemom;
  • Sredstva za registracijo, avtentikacijo in avtorizacijo naprav/oseb;
  • Baza podatkov, ki hrani operativne in arhivirane podatke:

Blockchain: kaj naj zgradimo PoC?

Uradno različico tega, kaj je Hyperledger Fabric, lahko preberete na Online, in na kratko, Hyperledger Fabric je odprtokodna platforma, ki vam omogoča gradnjo zasebnih verig blokov in izvajanje poljubnih pametnih pogodb, napisanih v programskih jezikih JS in Go. Oglejmo si pobližje arhitekturo Hyperledger Fabric in se prepričajmo, da je to univerzalen sistem, ki ima posebnosti le pri shranjevanju in zapisovanju podatkov. Posebnost je v tem, da se podatki, tako kot v vseh verigah blokov, shranjujejo v bloke, ki se v blokovno verigo umestijo le, če so udeleženci dosegli soglasje in po zapisu podatkov ni mogoče tiho popraviti ali izbrisati.

Arhitektura Hyperledger Fabric

Diagram prikazuje arhitekturo Hyperledger Fabric:

Blockchain: kaj naj zgradimo PoC?

Organizacije - organizacije vsebujejo vrstnike, torej blockchain obstaja zaradi podpore organizacij. Različne organizacije so lahko del istega kanala.

Channel - logična struktura, ki združuje vrstnike v skupine, torej. blockchain je nastavljen. Hyperledger Fabric lahko hkrati obdeluje več verig blokov z različno poslovno logiko.

Ponudnik storitev članstva (MSP) je CA (Certificate Authority) za izdajanje identitete in dodeljevanje vlog. Če želite ustvariti vozlišče, morate komunicirati z MSP.

Peer vozlišča — preverjanje transakcij, shranjevanje verige blokov, izvajanje pametnih pogodb in interakcija z aplikacijami. Vrstniki imajo identiteto (digitalno potrdilo), ki jo izda MSP. Za razliko od omrežja Bitcoin ali Etherium, kjer so vsa vozlišča enaka, imajo vozlišča različne vloge v Hyperledger Fabric:

  • Peer je lahko podprti vrstnik (EP) in izvajati pametne pogodbe.
  • Posredovanje vrstnika (CP) - shranite samo podatke v blockchain in posodobite "Svetovno stanje".
  • Anchor Peer (AP) - če v blockchainu sodeluje več organizacij, se za komunikacijo med njimi uporabljajo sidrni vrstniki. Vsaka organizacija mora imeti enega ali več sidrnih partnerjev. S pomočjo AP lahko vsak vrstnik v organizaciji pridobi informacije o vseh vrstnikih v drugih organizacijah. Uporablja se za sinhronizacijo informacij med dostopnimi točkami. trač protokol.
  • Vodja Peer - če ima organizacija več vrstnikov, bo le vodja vrstnika prejel bloke od storitve Naročanje in jih dal ostalim vrstnikom. Vodja je lahko statično ali dinamično izbran s strani vrstnikov v organizaciji. Protokol ogovarjanja se uporablja tudi za sinhronizacijo informacij o vodji.

Sredstva — entitete vrednosti, ki so shranjene v verigi blokov. Natančneje, to so podatki ključ-vrednost v formatu JSON. Prav ti podatki so zapisani v blokovni verigi Blockchain. Imajo zgodovino, ki je shranjena v verigi blokov, in trenutno stanje, ki je shranjeno v bazi podatkov »Svetovno stanje«. Podatkovne strukture se polnijo poljubno glede na poslovne naloge. Ni obveznih polj, edino priporočilo je, da morajo sredstva imeti lastnika in imeti vrednost.

Ledger - sestoji iz verige blokov Blockchain in podatkovne baze stanja Word, ki hrani trenutno stanje sredstev. Svetovna država uporablja LevelDB ali CouchDB.

Pametna pogodba — s pomočjo pametnih pogodb se implementira poslovna logika sistema. V Hyperledger Fabric se pametne pogodbe imenujejo verižna koda. S pomočjo verižne kode se določijo sredstva in transakcije nad njimi. V tehničnem jeziku so pametne pogodbe programski moduli, implementirani v programskih jezikih JS ali Go.

Politika odobritve - za vsako verižno kodo lahko nastavite pravilnike o tem, koliko in od koga morate pričakovati potrditve transakcije. Če pravilnik ni nastavljen, je privzeta nastavitev: »transakcijo mora potrditi kateri koli član katere koli organizacije v kanalu«. Primeri politik:

  • Transakcijo mora potrditi kateri koli skrbnik organizacije;
  • Potrditi mora kateri koli član ali stranka organizacije;
  • Potrditi mora katerega koli vrstnika organizacije.

Storitev naročanja - pakira transakcije v bloke in jih pošilja vrstnikom v kanalu. Zagotavlja dostavo sporočil vsem vrstnikom v omrežju. Uporablja se za industrijske sisteme Kafka posrednik sporočil, za razvoj in testiranje solo.

pretok klicev

Blockchain: kaj naj zgradimo PoC?

  • Aplikacija komunicira s Hyperledger Fabric z uporabo Go, Node.js ali Java SDK;
  • Odjemalec ustvari transakcijo tx in jo pošlje podpornikom;
  • Enak preveri odjemalčev podpis, dokonča transakcijo in pošlje potrditveni podpis nazaj odjemalcu. Verižna koda se izvede samo na vrstniku, ki potrdi, in rezultat njene izvedbe se pošlje vsem vrstnikom. Takšen algoritem dela se imenuje - PBFT (Practical Byzantine Fault Tolerant) konsenz. Razlikuje se od klasični BFT dejstvo, da je sporočilo poslano in se ne pričakuje potrditve od vseh udeležencev, ampak le od določenega niza;
  • Ko stranka prejme število odgovorov, ki ustreza politiki potrditve, pošlje transakcijo storitvi za naročanje;
  • Storitev naročanja oblikuje blok in ga pošlje vsem enakovrednim uporabnikom. Storitev Ordering zagotavlja, da so bloki zapisani zaporedno, kar odpravlja tako imenovane ledger fork (glej razdelek "Vilice");
  • Vrstniki prejmejo blok, znova preverijo politiko potrditve, zapišejo blok v verigo blokov in spremenijo stanje v DB »World state«.

Tisti. izkaže se delitev vlog med vozlišči. To zagotavlja razširljivost in varnost verige blokov:

  • Pametne pogodbe (verižna koda) izvajajo odobritev vrstnikov. To zagotavlja zaupnost pametnih pogodb, kot ne shranjujejo ga vsi udeleženci, ampak le podporniki.
  • Naročanje bi moralo delovati hitro. To je zagotovljeno z dejstvom, da Ordering samo oblikuje blok in ga pošlje fiksnemu nizu vodilnih vrstnikov.
  • Povezani vrstniki shranjujejo samo verigo blokov – lahko jih je veliko in ne zahtevajo veliko moči in takojšnjega dela.

Več arhitekturnih rešitev Hyperledger Fabric in zakaj deluje tako in ne drugače najdete tukaj: Izvori arhitekture ali tukaj: Hyperledger Fabric: porazdeljeni operacijski sistem za dovoljene verige blokov.

Torej, Hyperledger Fabric je resnično univerzalen sistem, s katerim lahko:

  • Implementirajte poljubno poslovno logiko z uporabo mehanizma pametnih pogodb;
  • Pisanje in prejemanje podatkov iz podatkovne baze blockchain v formatu JSON;
  • Dodelite in potrdite dostop do API-ja s pomočjo overitelja potrdil.

Zdaj, ko smo se malo pomirili s posebnostmi Hyperledger Fabric, naredimo končno nekaj koristnega!

Uvajanje verige blokov

Izjava o težavah

Naloga je vzpostaviti omrežje Citcoin z naslednjimi funkcijami: ustvariti račun, pridobiti stanje, napolniti račun, prenesti kovance z enega računa na drugega. Narišimo objektni model, ki ga bomo nadalje implementirali v pametno pogodbo. Torej, imeli bomo račune, ki so identificirani z imeni (ime) in vsebujejo stanje (stanje), ter seznam računov. Računi in seznam računov so v smislu sredstev Hyperledger Fabric. Temu primerno imajo zgodovino in trenutno stanje. Poskušal bom vizualno narisati:

Blockchain: kaj naj zgradimo PoC?

Zgornje številke so trenutno stanje, ki je shranjeno v bazi podatkov "Svetovno stanje". Pod njimi so slike, ki prikazujejo zgodovino, ki je shranjena v blockchainu. Trenutno stanje sredstev se spreminja s transakcijami. Sredstvo se spremeni samo v celoti, tako da kot rezultat transakcije nastane nov objekt, trenutna vrednost sredstva pa gre v zgodovino.

IBM Cloud

Ustvarimo račun v IBM oblak. Če želite uporabljati platformo blockchain, jo je treba nadgraditi na plačilo ob uporabi. Ta postopek morda ne bo hiter, ker IBM zahteva dodatne informacije in jih ročno preveri. Na pozitivni strani lahko rečem, da ima IBM dobra gradiva za usposabljanje, ki vam omogočajo uvajanje Hyperledger Fabric v njihov oblak. Všeč mi je bila naslednja serija člankov in primerov:

Sledijo posnetki zaslona platforme IBM Blockchain. To ni navodilo za ustvarjanje verige blokov, ampak le prikaz obsega naloge. Torej, za naše namene naredimo eno organizacijo:

Blockchain: kaj naj zgradimo PoC?

V njem ustvarimo vozlišča: Orderer CA, Org1 CA, Orderer Peer:

Blockchain: kaj naj zgradimo PoC?

Uporabnike začenjamo:

Blockchain: kaj naj zgradimo PoC?

Ustvarite kanal in ga poimenujte citcoin:

Blockchain: kaj naj zgradimo PoC?

V bistvu je Channel veriga blokov, torej se začne od ničelnega bloka (blok Genesis):

Blockchain: kaj naj zgradimo PoC?

Pisanje pametne pogodbe

/*
 * 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;

Intuitivno bi moralo biti tukaj vse jasno:

  • Obstaja več funkcij (AddAccount, GetAccounts, SendFrom, GetBalance, RefillBalance), ki jih bo demo program poklical z API-jem Hyperledger Fabric.
  • Funkciji SendFrom in RefillBalance ustvarjata dogodke (Event), ki jih bo prejel demo program.
  • Funkcija instantiranja se pokliče enkrat, ko je pametna pogodba instancirana. Pravzaprav se ne kliče enkrat, ampak vsakič, ko se različica pametne pogodbe spremeni. Zato je inicializacija seznama s prazno matriko slaba ideja, ker zdaj bomo ob spreminjanju različice pametne pogodbe izgubili trenutni seznam. Ampak nič, samo učim se).
  • Računi in seznam računov (računi) so podatkovne strukture JSON. JS se uporablja za obdelavo podatkov.
  • Trenutno vrednost sredstva lahko pridobite s klicem funkcije getState in jo posodobite s funkcijo putState.
  • Pri ustvarjanju računa se pokliče funkcija AddAccount, v kateri se naredi primerjava za največje število računov v blockchainu (maxAccounts = 5). In obstaja zastoj (opažen?), Kar vodi do neskončnega povečanja števila računov. Takšnim napakam se je treba izogibati

Nato naložimo pametno pogodbo v kanal in jo instanciramo:

Blockchain: kaj naj zgradimo PoC?

Ogledamo si transakcijo za namestitev pametne pogodbe:

Blockchain: kaj naj zgradimo PoC?

Oglejte si podrobnosti o našem kanalu:

Blockchain: kaj naj zgradimo PoC?

Kot rezultat dobimo naslednjo shemo omrežja blockchain v oblaku IBM. Na diagramu je tudi predstavitveni program, ki se izvaja v oblaku Amazon na virtualnem strežniku (podrobnosti o njem bodo v naslednjem razdelku):

Blockchain: kaj naj zgradimo PoC?

Ustvarjanje GUI za klice API Hyperledger Fabric

Hyperledger Fabric ima API, ki se lahko uporablja za:

  • Ustvarite kanal;
  • Peer povezave s kanalom;
  • Namestitev in instanciranje pametnih pogodb v kanalu;
  • Klicne transakcije;
  • Zahtevajte informacije o blockchainu.

Razvoj aplikacij

V našem predstavitvenem programu bomo API uporabljali samo za klicanje transakcij in zahtevanje informacij, ker. preostale korake smo že izvedli z IBM-ovo platformo blockchain. GUI napišemo z uporabo standardnega tehnološkega sklada: Express.js + Vue.js + Node.js. O tem, kako začeti ustvarjati sodobne spletne aplikacije, lahko napišete ločen članek. Tukaj bom pustil povezavo do serije predavanj, ki so mi bila najbolj všeč: Spletna aplikacija Full Stack z uporabo Vue.js in Express.js. Rezultat je aplikacija odjemalec-strežnik z znanim grafičnim vmesnikom v slogu Googlovega materialnega oblikovanja. API REST med odjemalcem in strežnikom je sestavljen iz več klicev:

  • HyperledgerDemo/v1/init - inicializirajte verigo blokov;
  • HyperledgerDemo/v1/accounts/list - pridobite seznam vseh računov;
  • HyperledgerDemo/v1/account?name=Bob&balance=100 - ustvarite račun Bob;
  • HyperledgerDemo/v1/info?account=Bob - pridobite informacije o računu Bob;
  • HyperledgerDemo/v1/transaction?from=Bob&to=Alice&volume=2 - prenesite dva kovanca od Boba do Alice;
  • HyperledgerDemo/v1/disconnect - prekinite povezavo z verigo blokov.

Opis API-ja s primeri Spletno mesto poštar je znan program za testiranje HTTP API.

Demo aplikacija v oblaku Amazon

Aplikacijo naložila Amazon, saj IBM še vedno ni mogel nadgraditi mojega računa in mi dovoliti ustvarjanja virtualnih strežnikov. Kako je bila domena pripeta na češnjo: www.citcoin.info. Še nekaj časa pustim prižgan strežnik, potem ga izključim, ker centi za najem kapljajo, citcoin kovanci pa še niso kotirani na borzi) V članek sem dal demo posnetke zaslona, ​​​​da je logika dela jasna. Demo aplikacija lahko:

  • Inicializirajte verigo blokov;
  • Ustvarite račun (vendar zdaj novega računa ni mogoče ustvariti, ker je bilo v verigi blokov doseženo največje število računov, določenih v pametni pogodbi);
  • Pridobite seznam računov;
  • Prenesite kovance citcoin med Alice, Bobom in Alexom;
  • Prejemanje dogodkov (vendar zdaj ni več možnosti za prikaz dogodkov, zato je zaradi poenostavitve v vmesniku napisano, da dogodki niso podprti);
  • Dnevnik dejanj.

Najprej inicializiramo verigo blokov:

Blockchain: kaj naj zgradimo PoC?

Nato zaženemo svoj račun, ne šalimo se s stanjem:

Blockchain: kaj naj zgradimo PoC?

Dobimo seznam vseh razpoložljivih računov:

Blockchain: kaj naj zgradimo PoC?

Izberemo pošiljatelja in prejemnika, dobimo njuna stanja. Če sta pošiljatelj in prejemnik ista, bo njegov račun napolnjen:

Blockchain: kaj naj zgradimo PoC?

V dnevniku spremljamo izvajanje transakcij:

Blockchain: kaj naj zgradimo PoC?

Pravzaprav je to vse z demo programom. Nato si lahko ogledate našo transakcijo v blockchainu:

Blockchain: kaj naj zgradimo PoC?

In splošen seznam transakcij:

Blockchain: kaj naj zgradimo PoC?

S tem smo uspešno zaključili implementacijo PoC za ustvarjanje omrežja Citcoin. Kaj je še treba storiti, da bi Citcoin postal polnopravno omrežje za prenos kovancev? Zelo malo:

  • V fazi ustvarjanja računa implementirajte generiranje zasebnega / javnega ključa. Zasebni ključ mora shraniti uporabniški račun, ki je javen v blockchainu.
  • Izvedite prenos kovancev, pri katerem se za identifikacijo uporabnika ne uporablja ime, temveč javni ključ.
  • Šifrirajte transakcije, ki gredo od uporabnika do strežnika z njegovim zasebnim ključem.

Zaključek

Implementirali smo omrežje Citcoin z naslednjimi funkcijami: dodajte račun, pridobite stanje, napolnite svoj račun, prenesite kovance z enega računa na drugega. Koliko nas je torej stala izdelava PoC?

  • Treba je preučiti blockchain na splošno in zlasti Hyperledger Fabric;
  • Naučite se uporabljati oblake IBM ali Amazon;
  • Naučite se programskega jezika JS in nekaj spletnega ogrodja;
  • Če je treba nekatere podatke shraniti ne v verigi blokov, ampak v ločeni bazi podatkov, se naučite, kako se na primer integrirati s PostgreSQL;
  • In nenazadnje – brez poznavanja Linuxa v sodobnem svetu nikamor!)

Seveda ne raketna znanost, vendar se morate spotiti!

Viri na GitHubu

Viri dani GitHub. Kratek opis repozitorija:
Katalog «strežnik» - Strežnik Node.js
Katalog «stranke» - Odjemalec Node.js
Katalog «blockchain» (vrednosti parametrov in ključev seveda ne delujejo in so podane le za primer):

  • pogodba — vir pametne pogodbe
  • denarnica - uporabniški ključi za uporabo API-ja Hyperledger Fabric.
  • *.cds - prevedene različice pametnih pogodb
  • Datoteke *.json – primeri konfiguracijskih datotek za uporabo API-ja Hyperledger Fabric

To je šele začetek!

Vir: www.habr.com

Dodaj komentar