Blockchain: ce PoC ar trebui să construim?

Ochii îți sunt frică și mâncărimea mâinilor!

În articolele anterioare, ne-am ocupat de tehnologiile pe care sunt construite blockchain-urile (Ce ar trebui să construim un blockchain?) și cazuri care pot fi implementate cu ajutorul lor (De ce ar trebui să construim un caz?). Este timpul să lucrezi cu mâinile tale! Pentru a implementa piloți și PoC (Proof of Concept), prefer să folosesc norii, deoarece... pot fi accesate de oriunde în lume și, de multe ori, nu este nevoie să pierdeți timpul cu instalarea plictisitoare a mediului, deoarece Există configurații prestabilite. Deci, să facem ceva simplu, de exemplu, o rețea pentru transferul de monede între participanți și să-i spunem modest Bitcoin. Pentru aceasta vom folosi cloud-ul IBM și blockchain-ul universal Hyperledger Fabric. În primul rând, să ne dăm seama de ce Hyperledger Fabric este numit blockchain universal?

Blockchain: ce PoC ar trebui să construim?

Hyperledger Fabric - un blockchain universal

În general, un sistem informațional universal este:

  • Un set de servere și un nucleu software care realizează logica de afaceri;
  • Interfețe pentru interacțiunea cu sistemul;
  • Instrumente pentru înregistrarea, autentificarea și autorizarea dispozitivelor/persoanelor;
  • Baza de date care stochează date operaționale și de arhivă:

Blockchain: ce PoC ar trebui să construim?

Versiunea oficială a ceea ce este Hyperledger Fabric poate fi citită la On-lineși, pe scurt, Hyperledger Fabric este o platformă opensource care vă permite să construiți blockchain-uri private și să executați contracte inteligente arbitrare scrise în limbajele de programare JS și Go. Să ne uităm în detaliu la arhitectura Hyperledger Fabric și să ne asigurăm că acesta este un sistem universal care are doar specificații pentru stocarea și înregistrarea datelor. Specificul este că datele, ca în toate blockchain-urile, sunt stocate în blocuri care sunt plasate pe blockchain numai dacă participanții ajung la un consens și după înregistrare datele nu pot fi corectate sau șterse în liniște.

Hyperledger Fabric Architecture

Diagrama prezintă arhitectura Hyperledger Fabric:

Blockchain: ce PoC ar trebui să construim?

Organizaţii — organizațiile conțin colegi, de ex. blockchain-ul există datorită sprijinului organizațiilor. Diferite organizații pot face parte din același canal.

Canal — o structură logică care unește colegii în grupuri, de ex. este specificat blockchain-ul. Hyperledger Fabric poate procesa simultan mai multe blockchain-uri cu o logică de afaceri diferită.

Furnizor de servicii de membru (MSP) este o CA (Autoritate de Certificare) pentru emiterea identității și atribuirea de roluri. Pentru a crea un nod, trebuie să interacționați cu MSP.

Nodurile egale — verificați tranzacțiile, stocați blockchain-ul, executați contracte inteligente și interacționați cu aplicațiile. Peers au o identitate (certificat digital), care este emis de MSP. Spre deosebire de rețeaua Bitcoin sau Etherium, unde toate nodurile au drepturi egale, în Hyperledger Fabric nodurile joacă roluri diferite:

  • Peer poate susținând egalul (EP) și să execute contracte inteligente.
  • Compania de angajament (CP) - salvați numai datele în blockchain și actualizați „Starea lumii”.
  • Anchor Peer (AP) - dacă mai multe organizații participă la blockchain, atunci pentru comunicarea între ei se utilizează peers ancora. Fiecare organizație trebuie să aibă unul sau mai mulți colegi de referință. Folosind AP, orice peer dintr-o organizație poate obține informații despre toți colegii din alte organizații. Folosit pentru sincronizarea informațiilor între AP-uri protocol de bârfă.
  • Lider Peer — dacă o organizație are mai mulți colegi, atunci doar liderul egalului va primi blocuri de la serviciul de Comandă și le va oferi restului colegilor. Liderul poate fi specificat fie static, fie selectat dinamic de către colegii din organizație. Protocolul de bârfă este, de asemenea, folosit pentru a sincroniza informațiile despre lideri.

Bunuri — entități care au valoare și sunt stocate pe blockchain. Mai precis, acestea sunt date cheie-valoare în format JSON. Aceste date sunt înregistrate în Blockchain. Au un istoric, care este stocat în blockchain, și o stare curentă, care este stocată în baza de date „World State”. Structurile de date sunt umplute în mod arbitrar, în funcție de sarcinile de afaceri. Nu există câmpuri obligatorii, singura recomandare este ca activele să aibă un proprietar și să fie valoroase.

carte mare — constă din Blockchain și baza de date de stare Word, care stochează starea curentă a activelor. Statul mondial folosește LevelDB sau CouchDB.

Contract inteligent — folosind contracte inteligente, se implementează logica de afaceri a sistemului. În Hyperledger Fabric, contractele inteligente sunt numite chaincode. Folosind codul de lanț, activele și tranzacțiile peste acestea sunt specificate. În termeni tehnici, contractele inteligente sunt module software implementate în limbajele de programare JS sau Go.

Politica de aprobare — pentru fiecare cod de lanț, puteți seta o politică privind câte confirmări pentru o tranzacție ar trebui să fie așteptate și de la cine. Dacă politica nu este setată, atunci valoarea implicită este: „tranzacția trebuie să fie confirmată de orice membru al oricărei organizații din canal”. Exemple de politici:

  • Tranzacția trebuie să fie aprobată de orice administrator al organizației;
  • Trebuie confirmat de orice membru sau client al organizației;
  • Trebuie să fie confirmat de orice organizație similară.

Serviciu de comenzi — împachetează tranzacțiile în blocuri și le trimite către colegii din canal. Garantează livrarea mesajelor către toți colegii din rețea. Folosit pentru sisteme industriale Broker de mesaje Kafka, pentru dezvoltare și testare Singur.

CallFlow

Blockchain: ce PoC ar trebui să construim?

  • Aplicația comunică cu Hyperledger Fabric folosind Go, Node.js sau Java SDK;
  • Clientul creează o tranzacție tx și o trimite către colegii de aprobare;
  • Peer-ul verifică semnătura clientului, finalizează tranzacția și trimite semnătura de aprobare înapoi clientului. Chaincode este executat numai pe peer-ul de aprobare, iar rezultatul executării acestuia este trimis tuturor peer-ului. Acest algoritm de lucru se numește consens PBFT (Practical Byzantine Fault Tolerant). Difera de BFT clasic faptul că mesajul este trimis și se așteaptă confirmarea nu de la toți participanții, ci doar de la un anumit set;
  • Dupa ce clientul a primit numarul de raspunsuri corespunzator politicii de avizare, acesta trimite tranzactia catre Serviciul de Comenzi;
  • Serviciul de comandă generează un bloc și îl trimite tuturor colegilor care commit. Serviciul de comandă asigură înregistrarea secvențială a blocurilor, ceea ce elimină așa-numita furcă de registru (vezi sectiunea "Furci");
  • Peers primesc un bloc, verifică din nou politica de aprobare, scrie blocul în blockchain și schimbă starea în DB „World state”.

Acestea. Aceasta are ca rezultat o împărțire a rolurilor între noduri. Acest lucru asigură că blockchain-ul este scalabil și sigur:

  • Contractele inteligente (codul de lanț) efectuează susținerea colegilor. Acest lucru asigură confidențialitatea contractelor inteligente, deoarece nu este stocat de toți participanții, ci doar de colegii care susțin.
  • Comanda ar trebui să funcționeze rapid. Acest lucru este asigurat de faptul că Ordering formează doar un bloc și îl trimite unui set fix de colegi lideri.
  • Peers care se angajează doar stochează blockchain-ul - pot fi mulți dintre ei și nu necesită multă putere și funcționare instantanee.

Mai multe detalii despre soluțiile arhitecturale ale Hyperledger Fabric și de ce funcționează astfel și nu altfel pot fi găsite aici: Originile arhitecturii sau aici: Hyperledger Fabric: un sistem de operare distribuit pentru blockchain-uri permise.

Deci, Hyperledger Fabric este un sistem cu adevărat universal cu ajutorul căruia puteți:

  • Implementați logica de afaceri arbitrară folosind mecanismul de contract inteligent;
  • Înregistrați și primiți date din baza de date blockchain în format JSON;
  • Acordați și verificați accesul la API folosind Autoritatea de certificare.

Acum că înțelegem puțin despre specificul Hyperledger Fabric, să facem în sfârșit ceva util!

Implementarea blockchain-ului

Declarație de problemă

Sarcina este de a implementa rețeaua Citcoin cu următoarele funcții: creați un cont, obțineți un sold, încărcați contul, transferați monede dintr-un cont în altul. Să desenăm un model de obiect, pe care îl vom implementa în continuare într-un contract inteligent. Deci, vom avea conturi care sunt identificate prin nume și care conțin un sold și o listă de conturi. Conturile și o listă de conturi sunt, în ceea ce privește activele Hyperledger Fabric. În consecință, au o istorie și o stare actuală. Voi încerca să desenez acest lucru clar:

Blockchain: ce PoC ar trebui să construim?

Cifrele de sus sunt starea curentă, care este stocată în baza de date „Starea lumii”. Sub ele sunt cifre care arată istoricul care este stocat în blockchain. Starea actuală a activelor este modificată de tranzacții. Activul se modifică numai ca întreg, astfel încât, în urma tranzacției, este creat un nou obiect, iar valoarea curentă a activului intră în istorie.

IBM Cloud

Ne creăm un cont în IBM cloud. Pentru a utiliza platforma blockchain, aceasta trebuie să fie actualizată la Pay-As-You-Go. Acest proces poate să nu fie rapid, deoarece... IBM solicită informații suplimentare și le verifică manual. Într-o notă pozitivă, pot spune că IBM are materiale de instruire bune care vă permit să implementați Hyperledger Fabric în cloud-ul lor. Mi-a plăcut următoarea serie de articole și exemple:

Următoarele sunt capturi de ecran ale platformei IBM Blockchain. Aceasta nu este o instrucțiune despre cum să creați un blockchain, ci pur și simplu o demonstrație a domeniului de aplicare a sarcinii. Deci, pentru scopurile noastre, facem o singură organizație:

Blockchain: ce PoC ar trebui să construim?

Creăm noduri în el: Orderer CA, Org1 CA, Orderer Peer:

Blockchain: ce PoC ar trebui să construim?

Cream utilizatori:

Blockchain: ce PoC ar trebui să construim?

Creați un canal și numiți-l citcoin:

Blockchain: ce PoC ar trebui să construim?

În esență, Channel este un blockchain, deci începe cu blocul zero (blocul Genesis):

Blockchain: ce PoC ar trebui să construim?

Scrierea unui contract inteligent

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

Intuitiv, totul ar trebui să fie clar aici:

  • Există mai multe funcții (AddAccount, GetAccounts, SendFrom, GetBalance, RefillBalance) pe care programul demo le va apela folosind API-ul Hyperledger Fabric.
  • Funcțiile SendFrom și RefillBalance generează evenimente pe care le va primi programul demo.
  • Funcția de instanțiere este apelată o dată când este instanțiat un contract inteligent. De fapt, se numește nu doar o dată, ci de fiecare dată când versiunea smart contract se schimbă. Prin urmare, inițializarea unei liste cu o matrice goală este o idee proastă, deoarece Acum, când schimbăm versiunea contractului inteligent, vom pierde lista curentă. Dar e în regulă, doar învăț).
  • Conturile și o listă de conturi sunt structuri de date JSON. JS este folosit pentru manipularea datelor.
  • Puteți obține valoarea curentă a unui activ folosind apelul funcției getState și o puteți actualiza folosind putState.
  • La crearea unui cont se apelează funcția AddAccount, în care se face o comparație pentru numărul maxim de conturi din blockchain (maxAccounts = 5). Și aici există un jamb (ai observat?), care duce la o creștere nesfârșită a numărului de conturi. Astfel de greșeli ar trebui evitate)

În continuare, încărcăm contractul inteligent în canal și îl instanțiem:

Blockchain: ce PoC ar trebui să construim?

Să ne uităm la tranzacția pentru instalarea Smart Contract:

Blockchain: ce PoC ar trebui să construim?

Să ne uităm la detaliile despre canalul nostru:

Blockchain: ce PoC ar trebui să construim?

Ca rezultat, obținem următoarea diagramă a unei rețele blockchain în cloud-ul IBM. Diagrama arată, de asemenea, un program demonstrativ care rulează în cloudul Amazon pe un server virtual (mai multe despre el în secțiunea următoare):

Blockchain: ce PoC ar trebui să construim?

Crearea unei GUI pentru apelurile API Hyperledger Fabric

Hyperledger Fabric are un API care poate fi folosit pentru:

  • Creați canal;
  • Conexiuni peer to channel;
  • Instalarea și instanțierea de contracte inteligente în canal;
  • Tranzacții de apelare;
  • Solicitați informații despre blockchain.

Dezvoltarea aplicației

În programul nostru demonstrativ vom folosi API-ul doar pentru a apela tranzacții și a solicita informații, deoarece Am finalizat deja pașii rămași folosind platforma IBM blockchain. Scriem o interfață grafică folosind o stivă de tehnologie standard: Express.js + Vue.js + Node.js. Puteți scrie un articol separat despre cum să începeți să creați aplicații web moderne. Aici voi lăsa un link către seria de prelegeri care mi-au plăcut cel mai mult: Aplicația web Full Stack folosind Vue.js și Express.js. Rezultatul este o aplicație client-server cu o interfață grafică familiară în stilul Google Material Design. API-ul REST dintre client și server constă din mai multe apeluri:

  • HyperledgerDemo/v1/init - inițializați blockchain-ul;
  • HyperledgerDemo/v1/accounts/list — obțineți o listă cu toate conturile;
  • HyperledgerDemo/v1/account?name=Bob&balance=100 — creați cont Bob;
  • HyperledgerDemo/v1/info?account=Bob — obțineți informații despre contul Bob;
  • HyperledgerDemo/v1/transaction?from=Bob&to=Alice&volume=2 - transferă două monede de la Bob la Alice;
  • HyperledgerDemo/v1/disconnect - închideți conexiunea la blockchain.

Descrierea API-ului cu exemple incluse în Site-ul poștașului - un program binecunoscut pentru testarea HTTP API.

Aplicație demonstrativă în cloud Amazon

Am încărcat aplicația pe Amazon pentru că... IBM încă nu a reușit să-mi actualizeze contul și să-mi permită să creez servere virtuale. Cum să adăugați o cireșă la domeniu: www.citcoin.info. Voi ține serverul pornit o vreme, apoi îl voi opri, pentru că... cenții de închiriat picură, iar monedele citcoin nu sunt încă listate la bursă) includ capturi de ecran ale demo-ului în articol, astfel încât logica lucrării să fie clară. Aplicația demo poate:

  • Inițializați blockchain-ul;
  • Creați un Cont (dar acum nu puteți crea un Cont nou, deoarece numărul maxim de conturi specificat în contractul inteligent a fost atins în blockchain);
  • Primiți o listă de Conturi;
  • Transferați monede citcoin între Alice, Bob și Alex;
  • Primiți evenimente (dar acum nu există nicio modalitate de a afișa evenimente, așa că pentru simplitate interfața spune că evenimentele nu sunt suportate);
  • Înregistrați acțiuni.

Mai întâi inițializam blockchain-ul:

Blockchain: ce PoC ar trebui să construim?

În continuare, ne creăm contul, nu pierdeți timpul cu soldul:

Blockchain: ce PoC ar trebui să construim?

Primim o listă cu toate conturile disponibile:

Blockchain: ce PoC ar trebui să construim?

Selectăm expeditorul și destinatarul și obținem soldurile acestora. Dacă expeditorul și destinatarul sunt aceiași, atunci contul său va fi completat:

Blockchain: ce PoC ar trebui să construim?

În jurnal monitorizăm execuția tranzacțiilor:

Blockchain: ce PoC ar trebui să construim?

De fapt, asta e tot cu programul demo. Mai jos puteți vedea tranzacția noastră în blockchain:

Blockchain: ce PoC ar trebui să construim?

Și lista generală a tranzacțiilor:

Blockchain: ce PoC ar trebui să construim?

Cu aceasta, am finalizat cu succes implementarea PoC pentru a crea rețeaua Citcoin. Ce altceva trebuie făcut pentru ca Citcoin să devină o rețea cu drepturi depline pentru transferul de monede? Foarte putin:

  • În etapa de creare a contului, implementați generarea unei chei private/publice. Cheia privată trebuie să fie stocată cu utilizatorul contului, cheia publică trebuie să fie stocată în blockchain.
  • Efectuați un transfer de monede în care o cheie publică, mai degrabă decât un nume, este folosită pentru a identifica utilizatorul.
  • Criptați tranzacțiile care merg de la utilizator la server cu cheia sa privată.

Concluzie

Am implementat rețeaua Citcoin cu următoarele funcții: adăugați un cont, obțineți un sold, încărcați contul, transferați monede dintr-un cont în altul. Deci, cât ne-a costat să construim un PoC?

  • Trebuie să studiezi blockchain-ul în general și Hyperledger Fabric în special;
  • Învață să folosești cloud-urile IBM sau Amazon;
  • Învățați limbajul de programare JS și un cadru web;
  • Dacă unele date trebuie stocate nu în blockchain, ci într-o bază de date separată, atunci învață să integrezi, de exemplu, cu PostgreSQL;
  • Și nu în ultimul rând - nu poți trăi în lumea modernă fără cunoștințe de Linux!)

Desigur, nu este știință rachetă, dar va trebui să muncești din greu!

Surse de pe GitHub

Surse puse GitHub. Scurtă descriere a depozitului:
Catalog «serverul» — Serverul Node.js
Catalog «client» — Client Node.js
Catalog «blockchain„(valorile parametrilor și cheile, desigur, nu funcționează și sunt date doar ca exemplu):

  • contract — codul sursă al contractului inteligent
  • portofel — chei de utilizator pentru utilizarea API-ului Hyperledger Fabric.
  • *.cds - versiuni compilate de contracte inteligente
  • Fișiere *.json - exemple de fișiere de configurare pentru utilizarea API-ului Hyperledger Fabric

Este doar începutul!

Sursa: www.habr.com

Adauga un comentariu