Blockchain: wat kost het ons om een PoC op te zetten?

De ogen zijn bang, maar de handen jeuken!

In eerdere artikelen hebben we de technologieën behandeld waarop blockchains zijn gebouwd (Wat kost het ons om een blockchain te bouwen?) en de cases die daarmee gerealiseerd kunnen worden (Wat kost het om een case te bouwen?). Het is tijd om aan de slag te gaan! Voor het realiseren van pilots en PoC (Proof of Concept) geef ik de voorkeur aan clouds, omdat ze vanaf elke locatie ter wereld toegankelijk zijn en je vaak geen tijd hoeft te verspillen aan het vervelende installeren van omgevingen, aangezien er vooraf geïnstalleerde configuraties zijn. Laten we iets eenvoudigs doen, bijvoorbeeld een netwerk voor het overdragen van munten tussen deelnemers en het bescheiden de naam CitoCoin geven. Hiervoor gaan we de cloud van IBM en de universele blockchain Hyperledger Fabric gebruiken. Laten we eerst begrijpen waarom Hyperledger Fabric een universele blockchain wordt genoemd.

Blockchain: wat kost het ons om een PoC op te zetten?

Hyperledger Fabric — de universele blockchain

In algemene termen is een universeel informatiesysteem:

  • Een set servers en een programmatische kern die de bedrijfslogica uitvoert;
  • Interfaces voor interactie met het systeem;
  • Middelen voor registratie, authenticatie en autorisatie van apparaten/mensen;
  • Een database die operationele en archiefgegevens opslaat:

Blockchain: wat kost het ons om een PoC op te zetten?

De officiƫle versie van wat Hyperledger Fabric is, kan worden gelezen op website, maar kort samengevat is Hyperledger Fabric een opensource platform waarmee gesloten blockchains kunnen worden gebouwd en willekeurige smart contracts kunnen worden uitgevoerd die zijn geschreven in de programmeertalen JS en Go. Laten we de architectuur van Hyperledger Fabric gedetailleerd bekijken en ervoor zorgen dat dit een universeel systeem is, waarbij alleen de specificiteit van het opslaan en schrijven van gegevens bestaat. De specificiteit is dat gegevens, zoals in alle blockchains, in blokken worden opgeslagen, die alleen in de blockchain worden geplaatst als de deelnemers consensus hebben bereikt en na opname kunnen de gegevens niet ongemerkt worden gewijzigd of verwijderd.

Architectuur van Hyperledger Fabric

In het diagram is de architectuur van Hyperledger Fabric weergegeven:

Blockchain: wat kost het ons om een PoC op te zetten?

Organisaties — organisaties bevatten peers, zodat de blockchain bestaat dankzij de ondersteuning van organisaties. Verschillende organisaties kunnen deel uitmaken van ƩƩn channel.

Channel — een logische structuur die peers in groepen verenigt, zodat de blockchain wordt gedefinieerd. Hyperledger Fabric kan tegelijkertijd meerdere blockchains verwerken met verschillende bedrijfslogica.

Membership Services Provider (MSP) — dit is de CA (Certificate Authority) voor het verstrekken van identiteiten en het toewijzen van rollen. Voor het creĆ«ren van een node moet interactie plaatsvinden met de MSP.

Peer-nodes — controleren transacties, slaan de blockchain op, voeren smart contracts uit en interageren met applicaties. Peer-nodes hebben een identiteit (digitale certificaat), dat wordt uitgegeven door MSP. In tegenstelling tot netwerken zoals Bitcoin of Ethereum, waar alle nodes gelijkwaardig zijn, spelen nodes in Hyperledger Fabric verschillende rollen:

  • Een peer kan zijn endorsing peer (EP) en smart contracts uitvoeren.
  • Committing peer (CP) – slaat alleen gegevens op in de blockchain en actualiseert de "World state".
  • Anchor Peer (AP) – als er meerdere organisaties in de blockchain deelnemen, worden anchor peers gebruikt voor de communicatie tussen hen. Elke organisatie moet ƩƩn of meerdere anchor peers hebben. Met AP kan elke peer binnen een organisatie informatie krijgen over alle peers in andere organisaties. Voor de synchronisatie van informatie tussen AP's wordt het gossipprotocol.
  • Leader Peer – als een organisatie meerdere peers heeft, zal alleen de leader peer blokken ontvangen van de Ordering service en deze aan de andere peers doorgeven. De leider kan zowel statisch worden ingesteld als dynamisch worden gekozen door peers binnen de organisatie. Voor de synchronisatie van informatie over de leiders wordt ook het gossipprotocol gebruikt.

Assets – entiteiten met waarde die worden opgeslagen in de blockchain. Meer specifiek zijn dit key-value gegevens in JSON-formaat. Deze gegevens worden vastgelegd in de blockchain "Blockchain". Ze hebben een geschiedenis, die in de blockchain wordt opgeslagen, en een huidige staat, die in de database "World state" wordt opgeslagen. De datastructuren worden willekeurig gevuld, afhankelijk van de zakelijke behoeften. Er zijn geen verplichte velden, de enige aanbeveling is dat assets een eigenaar moeten hebben en waarde moeten vertegenwoordigen.

Ledger – bestaat uit de blockchain "Blockchain" en de database "World state", waarin de huidige staat van de assets wordt opgeslagen. World state maakt gebruik van LevelDB of CouchDB.

Slim contract – met behulp van smart contracts wordt de bedrijfslogica van het systeem geĆÆmplementeerd. In Hyperledger Fabric worden smart contracts chaincode genoemd. Met chaincode worden assets en transacties daarop gedefinieerd. Technisch gesproken zijn smart contracts softwaremodules die zijn geĆÆmplementeerd in programmeertalen zoals JS of Go.

Endorsement policy – voor elke chaincode kan worden vastgesteld welke en hoeveel bevestigingen voor een transactie nodig zijn van wie. Als er geen beleid is vastgesteld, geldt standaard: "de transactie moet worden goedgekeurd door elk lid (member) van elke organisatie in het kanaal". Voorbeelden van beleidsregels:

  • De transactie moet worden bevestigd door een administrator van de organisatie;
  • Moet bevestigd worden door een lid of klant van de organisatie;
  • Moet bevestigd worden door een peer van de organisatie.

Ordering service — verpakt transacties in blokken en verzendt deze naar de peers in het kanaal. Het garandeert de levering van berichten aan alle peers in het netwerk. Voor industriĆ«le systemen wordt gebruikt berichtenbroker Kafka, voor ontwikkeling en testen Solo.

CallFlow

Blockchain: wat kost het ons om een PoC op te zetten?

  • De applicatie communiceert met Hyperledger Fabric via Go, Node.js of Java SDK;
  • De client creĆ«ert de transactie tx en stuurt deze naar de endorsing peers;
  • De peer controleert de handtekening van de client, voert de transactie uit en stuurt de endorsement signature terug naar de client. Chaincode wordt alleen uitgevoerd op de endorsing peer en het resultaat van de uitvoering wordt naar alle peers verzonden. Dit werkalgoritme wordt PBFT (Practical Byzantine Fault Tolerant) consensus genoemd. Dit verschilt van klassieke BFT doordat het bericht wordt verzonden en een bevestiging wordt verwacht niet van alle deelnemers, maar alleen van een bepaalde set;
  • Nadat de client het aantal antwoorden heeft ontvangen dat overeenkomt met de endorsement policy, stuurt hij de transactie naar de Ordering service;
  • De Ordering service vormt een blok en verzendt dit naar alle committing peers. De Ordering service zorgt voor een consistente opname van blokken, waardoor zogenaamde ledger forks worden uitgesloten (zie sectie 'Forks');
  • De peers ontvangen het blok, controleren opnieuw de endorsement policy, registreren het blok in de blockchain en wijzigen de status in de 'World state' DB.

Dat is, er is een scheiding van rollen tussen de knopen. Dit zorgt voor schaalbaarheid en veiligheid van de blockchain:

  • Slimme contracten (chaincode) worden uitgevoerd door de endorsing peers. Dit waarborgt de vertrouwelijkheid van slimme contracten, omdat het niet bij alle deelnemers is opgeslagen, maar alleen op de endorsing peers.
  • Ordering moet snel werken. Dit wordt mogelijk gemaakt doordat Ordering alleen blokken vormt en deze naar een vaste set van leader peers verzendt.
  • Committing peers slaan alleen de blockchain op — er kunnen er veel zijn en ze vereisen geen grote kracht of directe werking.

Meer informatie over de architectonische oplossingen van Hyperledger Fabric en waarom het op deze manier werkt, kan hier worden bekeken: Architecture Origins of hier: Hyperledger Fabric: A Distributed Operating System for Permissioned Blockchains.

Dus, Hyperledger Fabric is echt een veelzijdig systeem waarmee je kunt:

  • Arbitraire bedrijfslogica implementeren met behulp van slimme contracten;
  • Gegevens opnemen en ophalen uit een blockchain-database in JSON-formaat;
  • Toegang tot de API verlenen en controleren met behulp van een Certificate Authority.

Laten we iets nuttigs gaan doen nu we een beetje begrijpen van de specificaties van Hyperledger Fabric!

Blockchain implementeren

Taakstelling

De taak is om een Citcoin-netwerk te implementeren met de volgende functies: een account aanmaken, saldo opvragen, rekening aanvullen, munten van het ene account naar het andere overmaken. Laten we een objectmodel schetsen dat we vervolgens in een smart contract zullen implementeren. We hebben dus accounts die worden geĆÆdentificeerd door namen (name) en een saldo (balance) bevatten, en een lijst van accounts. Accounts en de lijst van accounts zijn in de terminologie van Hyperledger Fabric assets. Ze hebben respectievelijk een geschiedenis en een huidige status. Ik zal proberen dit visueel weer te geven:

Blockchain: wat kost het ons om een PoC op te zetten?

De bovenste figuren zijn de huidige status, die wordt opgeslagen in de 'World state' database. Onder hen zijn de figuren die de geschiedenis tonen, die in de blockchain zijn opgeslagen. De huidige status van assets verandert door transacties. Een asset wordt alleen geheel gewijzigd, daarom wordt er na het uitvoeren van een transactie een nieuw object aangemaakt, en de huidige waarde van de asset gaat naar de geschiedenis.

IBM Cloud

Laten we een account aanmaken in de IBM Cloud. Voor het gebruik van het blockchainplatform moet het worden geüpgraded naar Pay-As-You-Go. Dit proces kan niet snel zijn, omdat IBM aanvullende informatie aanvraagt en deze handmatig controleert. Positief is dat IBM goede leermaterialen heeft die het mogelijk maken om Hyperledger Fabric in hun cloud in te zetten. Ik vond de volgende cyclus van artikelen en voorbeelden leuk:

Hieronder staan schermafbeeldingen van het IBM Blockchain-platform. Dit is geen handleiding voor het maken van een blockchain, maar gewoon een demonstratie van de omvang van de taak. Dus, voor onze doeleinden maken we ƩƩn organisatie:

Blockchain: wat kost het ons om een PoC op te zetten?

Daar creƫren we nodes: Orderer CA, Org1 CA, Orderer Peer:

Blockchain: wat kost het ons om een PoC op te zetten?

We maken gebruikers aan:

Blockchain: wat kost het ons om een PoC op te zetten?

We creƫren een kanaal en noemen het citcoin:

Blockchain: wat kost het ons om een PoC op te zetten?

In wezen is een kanaal een blockchain, dus het begint met een nulblok (Genesis block):

Blockchain: wat kost het ons om een PoC op te zetten?

We schrijven een smart contract

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

IntuĆÆtief moet hier alles duidelijk zijn:

  • Er zijn verschillende functies (AddAccount, GetAccounts, SendFrom, GetBalance, RefillBalance) die het demo-programma zal aanroepen met behulp van de Hyperledger Fabric API.
  • De functies SendFrom en RefillBalance genereren evenementen (Event) die het demo-programma zal ontvangen.
  • De functie instantiate wordt eenmaal aangeroepen bij het instantiĆ«ren van een smart contract. In werkelijkheid wordt deze niet ƩƩn keer aangeroepen, maar elke keer dat de versie van het smart contract verandert. Daarom is het initialiseren van de lijst met een lege array een slecht idee, omdat we nu de huidige lijst verliezen bij de wijziging van de versie van het smart contract. Maar goed, ik leer alleen maar).
  • Accounts en de lijst van accounts (accounts) zijn JSON-gegevensstructuren. Voor gegevensmanipulaties wordt JS gebruikt.
  • De huidige waarde van een asset kan worden verkregen met de functie getState, en kan worden bijgewerkt met putState.
  • Bij het aanmaken van een Account wordt de functie AddAccount aangeroepen, waarin de vergelijking wordt gemaakt met het maximum aantal accounts in de blockchain (maxAccounts = 5). En hier zit een fout (opgemerkt?), die leidt tot een oneindige groei van het aantal accounts. Dit soort fouten moet je vermijden)

Laten we nu het smart contract in het Channel laden en het instantiƫren:

Blockchain: wat kost het ons om een PoC op te zetten?

Laten we de transactie voor het instellen van het Smart Contract bekijken:

Blockchain: wat kost het ons om een PoC op te zetten?

Laten we de details van ons Channel bekijken:

Blockchain: wat kost het ons om een PoC op te zetten?

Als resultaat krijgen we het volgende schema van het blockchain-netwerk in de cloud van IBM. Ook op het schema staat een demo-applicatie die draait in de cloud van Amazon op een virtuele server (meer daarover in de volgende sectie):

Blockchain: wat kost het ons om een PoC op te zetten?

GUI maken voor het aanroepen van de Hyperledger Fabric API

Hyperledger Fabric heeft een API die kan worden gebruikt voor:

  • Het aanmaken van een channel;
  • Het verbinden van een peer aan een channel;
  • Het installeren en instantiĆ«ren van smart contracts in het channel;
  • Het aanroepen van transacties;
  • Informatie opvragen in de blockchain.

Applicatieontwikkeling

In onze demo-applicatie gebruiken we de API alleen voor het aanroepen van transacties en het opvragen van informatie, aangezien we de andere stappen al hebben uitgevoerd met behulp van het blockchain-platform van IBM. We schrijven de GUI met behulp van de standaardtechnologiestack: Express.js + Vue.js + Node.js. Hoe je moderne webapplicaties kunt beginnen te maken, kan in een apart artikel worden behandeld. Hier laat ik een link achter naar een serie lezingen die ik het leukst vond: Full Stack Web App using Vue.js & Express.js. Het resultaat is een client-serverapplicatie met een bekend grafisch interface in de stijl van Material Design van Google. REST API tussen de client en de server bestaat uit verschillende aanroepen:

  • HyperledgerDemo/v1/init — blockchain initialiseren;
  • HyperledgerDemo/v1/accounts/list — lijst van alle accounts ophalen;
  • HyperledgerDemo/v1/account?name=Bob&balance=100 — Bob account aanmaken;
  • HyperledgerDemo/v1/info?account=Bob — informatie over Bob account ophalen;
  • HyperledgerDemo/v1/transaction?from=Bob&to=Alice&volume=2 — twee munten overmaken van Bob naar Alice;
  • HyperledgerDemo/v1/disconnect — verbindt met de blockchain.

De API-beschrijving met voorbeelden heb ik geplaatst op de site 'Postman' — een wereldwijd bekend programma voor het testen van HTTP-API's.

Demo-applicatie in de Amazon-cloud.

Ik heb de applicatie geüpload naar Amazon, omdat IBM nog steeds mijn account niet heeft geüpgraded en ik geen virtuele servers kan aanmaken. Als kers op de taart heb ik het domein toegevoegd: www.citcoin.info. Ik houd de server een beetje aan, daarna zet ik hem uit, omdat de kosten voor de huur oplopen en de citcoin-munten nog niet op de beurs worden verhandeld) Ik voeg screenshots van de demo toe om de werklogica te verduidelijken. De demo-applicatie kan:

  • De blockchain initialiseren;
  • Een account aanmaken (maar op dit moment kan er geen nieuw account worden aangemaakt, omdat het maximale aantal accounts in het smart contract bereikt is);
  • Een lijst van accounts opvragen;
  • Citcoin-munten overdragen tussen Alice, Bob en Alex;
  • Gebeurtenissen ontvangen (maar op dit moment kunnen gebeurtenissen niet worden getoond, daarom staat er voor de eenvoud in de interface dat gebeurtenissen niet worden ondersteund);
  • Acties loggen.

Laten we eerst de blockchain initialiseren:

Blockchain: wat kost het ons om een PoC op te zetten?

Vervolgens maken we een account aan, laten we niet zuinig zijn met het saldo:

Blockchain: wat kost het ons om een PoC op te zetten?

Laten we een lijst van alle beschikbare accounts opvragen:

Blockchain: wat kost het ons om een PoC op te zetten?

We kiezen een verzender en ontvanger, en bekijken hun saldi. Als de verzender en ontvanger dezelfde zijn, wordt zijn rekening aangevuld:

Blockchain: wat kost het ons om een PoC op te zetten?

In het log volgen we de uitvoering van transacties:

Blockchain: wat kost het ons om een PoC op te zetten?

Dat was het dan met de demo-applicatie. Laten we nu onze transactie in de blockchain bekijken:

Blockchain: wat kost het ons om een PoC op te zetten?

En de algemene lijst van transacties:

Blockchain: wat kost het ons om een PoC op te zetten?

Hiermee hebben we de implementatie van de PoC voor het opzetten van het Citcoin-netwerk succesvol afgerond. Wat moet er nog meer gebeuren om Citcoin een volwaardig netwerk voor het overdragen van munten te maken? Heel weinig:

  • Bij het aanmaken van een account moet de generatie van een privĆ©-/publieke sleutel worden gerealiseerd. De privĆ©sleutel moet bij de gebruiker van het account worden bewaard, de publieke sleutel in de blockchain.
  • Doe een muntoverdracht waarin de identificatie van de gebruiker niet via de naam, maar via de publieke sleutel verloopt.
  • Versleutel transacties die van de gebruiker naar de server gaan met zijn privĆ©sleutel.

Conclusie

We hebben het Citcoin-netwerk gerealiseerd met de functies: account toevoegen, saldo opvragen, rekening aanvullen, munten van de ene rekening naar de andere overdragen. Dus, wat heeft het ons gekost om de PoC te bouwen?

  • We moeten de blockchain in het algemeen en Hyperledger Fabric in het bijzonder bestuderen;
  • Leren om gebruik te maken van IBM- of Amazon-cloudservices;
  • De programmeertaal JS leren en een webframework kiezen;
  • Als bepaalde gegevens niet in de blockchain, maar in een aparte database moeten worden opgeslagen, leer dan bijvoorbeeld te integreren met PostgreSQL;
  • En als laatste op de lijst, maar niet minder belangrijk - zonder kennis van Linux kom je de moderne wereld niet door!)

Natuurlijk, het is geen rocket science, maar je moet wel je best doen!

Bronbestanden op GitHub

De broncodes zijn geplaatst op GitHub. Korte beschrijving van de repository:
Catalogus «server» - Node.js server
Catalogus «client» - Node.js client
Catalogus «blockchain» (de parameterwaarden en sleutels zijn natuurlijk niet werkend en alleen ter illustratie):

  • contract - broncode van het smart contract
  • wallet - gebruikerssleutels voor het gebruik van de Hyperledger Fabric API.
  • *.cds - gecompileerde versies van smart contracts
  • *.json bestanden - voorbeelden van configuratiebestanden voor het gebruik van de Hyperledger Fabric API

Dit is pas het begin!

Bron: habr.com

Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers šŸ”„ Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers | ProHoster