Blockchain: co bychom měli postavit PoC?

Oči se bojí a ruce svrbí!

V předchozích článcích jsme se zabývali technologiemi, na kterých jsou blockchainy postaveny (Co bychom měli vybudovat blockchain?) a případy, které lze s jejich pomocí realizovat (Kolik nás stojí stavba pouzdra?). Je čas pracovat rukama! Pro implementaci pilotů a PoC (Proof of Concept) používám raději cloudy, protože. mají přístup odkudkoli na světě a často není potřeba trávit čas únavnou instalací prostředí, protože. Existují přednastavené konfigurace. Udělejme tedy něco jednoduchého, jako je síť pro převod coinů mezi účastníky a nazvěme to skromně Citcoin. K tomu využijeme cloud IBM a univerzální blockchain Hyperledger Fabric. Nejprve pojďme zjistit, proč se Hyperledger Fabric nazývá univerzálním blockchainem?

Blockchain: co bychom měli postavit PoC?

Hyperledger Fabric – univerzální blockchain

Obecně řečeno, univerzální informační systém je:

  • Sada serverů a softwarového jádra, které provádí obchodní logiku;
  • Rozhraní pro interakci se systémem;
  • Prostředky pro registraci, autentizaci a autorizaci zařízení / osob;
  • Databáze uchovávající provozní a archivovaná data:

Blockchain: co bychom měli postavit PoC?

Oficiální verzi toho, co Hyperledger Fabric je, si můžete přečíst na webové stránky, a stručně řečeno, Hyperledger Fabric je platforma s otevřeným zdrojovým kódem, která vám umožňuje budovat soukromé blockchainy a provádět libovolné chytré smlouvy napsané v programovacích jazycích JS a Go. Pojďme se blíže podívat na architekturu Hyperledger Fabric a přesvědčit se, že se jedná o univerzální systém, který má specifika pouze pro ukládání a záznam dat. Specifikum spočívá v tom, že data jsou stejně jako ve všech blockchainech ukládána do bloků, které se do blockchainu umisťují pouze v případě, že účastníci dosáhnou konsensu a po zaznamenání nelze data potichu opravit nebo smazat.

Hyperledger Fabric Architecture

Diagram ukazuje architekturu Hyperledger Fabric:

Blockchain: co bychom měli postavit PoC?

organizace - organizace obsahují vrstevníky, tak blockchain existuje díky podpoře organizací. Různé organizace mohou být součástí stejného kanálu.

Kanál - logická struktura, která spojuje vrstevníky do skupin, tedy. blockchain je nastaven. Hyperledger Fabric dokáže současně zpracovávat více blockchainů s různou obchodní logikou.

Poskytovatel členských služeb (MSP) je CA (Certificate Authority) pro vydávání identity a přidělování rolí. Chcete-li vytvořit uzel, musíte komunikovat s MSP.

Peer uzly — ověřovat transakce, ukládat blockchain, provádět chytré smlouvy a komunikovat s aplikacemi. Peers mají identitu (digitální certifikát) vydanou MSP. Na rozdíl od sítě Bitcoin nebo Etherium, kde jsou všechny uzly stejné, hrají uzly v Hyperledger Fabric různé role:

  • Peer může být schvalující vrstevník (EP) a provádět chytré smlouvy.
  • Zavazující se peer (CP) – pouze ukládat data do blockchainu a aktualizovat „Světový stav“.
  • Anchor Peer (AP) – pokud se blockchainu účastní několik organizací, ke komunikaci mezi nimi se používají kotevní peerové. Každá organizace musí mít jednoho nebo více kotevních kolegů. S pomocí AP může každý peer v organizaci získat informace o všech peerech v jiných organizacích. Používá se k synchronizaci informací mezi AP. drbní protokol.
  • Vedoucí Peer - pokud má organizace několik vrstevníků, pak bloky od objednávkové služby obdrží pouze vedoucí partnera a rozdá je ostatním kolegům. Vedoucí může být nastaven staticky nebo dynamicky vybraný kolegy v organizaci. Gossip protokol se také používá k synchronizaci informací vedoucích.

Měny — hodnotné entity, které jsou uloženy v blockchainu. Konkrétně se jedná o data klíč–hodnota ve formátu JSON. Právě tato data jsou zaznamenána v blockchainu blockchainu. Mají historii, která je uložena na blockchainu a aktuální stav, který je uložen v databázi „World state“. Datové struktury se vyplňují libovolně v závislosti na obchodních úkolech. Nejsou zde žádná povinná pole, jediným doporučením je, že aktiva musí mít vlastníka a mít hodnotu.

účetní kniha - skládá se z blockchainu blockchainu a databáze stavu Word, která uchovává aktuální stav aktiv. Světový stát používá LevelDB nebo CouchDB.

Inteligentní smlouva — pomocí chytrých kontraktů je implementována obchodní logika systému. V Hyperledger Fabric se chytré smlouvy nazývají řetězový kód. Pomocí řetězového kódu jsou specifikována aktiva a transakce nad nimi. V technickém jazyce jsou chytré smlouvy softwarové moduly implementované v programovacích jazycích JS nebo Go.

Zásady schvalování - pro každý řetězový kód můžete nastavit zásady, kolik a od koho potřebujete potvrzení transakce očekávat. Pokud tato zásada není nastavena, výchozí nastavení je: „transakce musí být potvrzena kterýmkoli členem jakékoli organizace v kanálu“. Příklady zásad:

  • Transakci musí potvrdit kterýkoli správce organizace;
  • Musí být potvrzeno kterýmkoli členem nebo klientem organizace;
  • Musí potvrdit kterýkoli protějšek organizace.

Objednávkový servis - balí transakce do bloků a odesílá je kolegům v kanálu. Zajišťuje doručení zpráv všem kolegům v síti. Používá se pro průmyslové systémy Zprostředkovatel zpráv Kafka, pro vývoj a testování sólo.

tok hovorů

Blockchain: co bychom měli postavit PoC?

  • Aplikace spolupracuje s Hyperledger Fabric pomocí Go, Node.js nebo Java SDK;
  • Klient vytvoří transakční tx a odešle jej schvalujícím kolegům;
  • Partner ověří podpis klienta, dokončí transakci a odešle schvalovací podpis zpět klientovi. Řetězový kód je spuštěn pouze na schvalujícím peeru a výsledek jeho spuštění je odeslán všem peerům. Takový algoritmus práce se nazývá konsensus PBFT (Practical Byzantine Fault Tolerant). Se liší od klasické BFT skutečnost, že zpráva je odeslána a potvrzení se očekává ne od všech účastníků, ale pouze od určité množiny;
  • Poté, co klient obdrží počet odpovědí odpovídající zásadám schvalování, odešle transakci službě Objednávání;
  • Objednávková služba vytvoří blok a odešle jej všem zavazujícím se kolegům. Služba Objednávání zajišťuje postupný zápis bloků, což eliminuje tzv. ledger fork (viz sekce "Vidlice");
  • Peers obdrží blok, znovu zkontroluje politiku schvalování, zapíše blok do blockchainu a změní stav v databázi „Světový stav“.

Tito. ukazuje se rozdělení rolí mezi uzly. To zajišťuje škálovatelnost a bezpečnost blockchainu:

  • Inteligentní smlouvy (řetězový kód) provádějí schvalování kolegů. Tím je zajištěna důvěrnost smart kontraktů, as neukládají jej všichni účastníci, ale pouze schvalující kolegové.
  • Objednávka by měla fungovat rychle. To je zajištěno tím, že Ordering tvoří pouze blok a posílá jej pevné sadě vedoucích vrstevníků.
  • Pověření peeři pouze ukládají blockchain – může jich být mnoho a nevyžadují mnoho energie a okamžité práce.

Více architektonických řešení Hyperledger Fabric a proč to funguje tak a ne jinak najdete zde: Počátky architektury nebo zde: Hyperledger Fabric: Distribuovaný operační systém pro povolené blockchainy.

Hyperledger Fabric je tedy skutečně univerzální systém, se kterým můžete:

  • Implementujte libovolnou obchodní logiku pomocí mechanismu inteligentních smluv;
  • Zápis a příjem dat z blockchainové databáze ve formátu JSON;
  • Udělte a ověřte přístup k rozhraní API pomocí certifikační autority.

Nyní, když jsme trochu vymazali specifika Hyperledger Fabric, pojďme konečně udělat něco užitečného!

Nasazení blockchainu

Formulace problému

Úkolem je implementovat síť Citcoin s následujícími funkcemi: vytvořit účet, získat zůstatek, doplnit účet, převést coiny z jednoho účtu na druhý. Nakreslíme si objektový model, který dále implementujeme do chytré smlouvy. Budeme tedy mít účty, které jsou identifikovány jmény (název) a obsahují zůstatek (zůstatek) a seznam účtů. Účty a seznam účtů jsou z hlediska aktiv Hyperledger Fabric. Podle toho mají historii a současný stav. Pokusím se to nakreslit vizuálně:

Blockchain: co bychom měli postavit PoC?

Nejvyšší čísla jsou aktuální stav, který je uložen v databázi "World state". Pod nimi jsou obrázky ukazující historii, která je uložena v blockchainu. Současný stav aktiv se mění transakcemi. Aktivum se mění pouze jako celek, takže v důsledku transakce vzniká nový objekt a aktuální hodnota aktiva jde do historie.

IBM Cloud

Vytvoříme účet v cloud IBM. Chcete-li používat blockchainovou platformu, musí být upgradována na Pay-As-You-Go. Tento proces nemusí být rychlý, protože IBM si vyžádá další informace a ručně je ověří. Pozitivně mohu říci, že IBM má dobré školicí materiály, které umožňují nasazení Hyperledger Fabric v jejich cloudu. Líbila se mi následující série článků a příkladů:

Níže jsou uvedeny snímky obrazovky platformy IBM Blockchain. Nejedná se o návod k vytvoření blockchainu, ale pouze o ukázku rozsahu úkolu. Pro naše účely tedy vytváříme jednu organizaci:

Blockchain: co bychom měli postavit PoC?

Vytváříme v něm uzly: Orderer CA, Org1 CA, Orderer Peer:

Blockchain: co bychom měli postavit PoC?

Začínáme s uživateli:

Blockchain: co bychom měli postavit PoC?

Vytvořte kanál a nazvěte jej citcoin:

Blockchain: co bychom měli postavit PoC?

Channel je v podstatě blockchain, takže začíná od nulového bloku (blok Genesis):

Blockchain: co bychom měli postavit PoC?

Sepsání chytré smlouvy

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

Intuitivně by zde mělo být vše jasné:

  • Existuje několik funkcí (AddAccount, GetAccounts, SendFrom, GetBalance, RefillBalance), které bude demo program volat pomocí Hyperledger Fabric API.
  • Funkce SendFrom a RefillBalance generují události (Event), které demo program obdrží.
  • Funkce instantiate je volána jednou, když je vytvořena instance smart kontraktu. Ve skutečnosti se nevolá jednou, ale pokaždé, když se změní verze chytré smlouvy. Proto je inicializace seznamu s prázdným polem špatný nápad, protože nyní při změně verze chytré smlouvy o aktuální seznam přijdeme. Ale nic, teprve se učím).
  • Účty a seznam účtů (účtů) jsou datové struktury JSON. JS se používá pro manipulaci s daty.
  • Aktuální hodnotu aktiva můžete získat voláním funkce getState a aktualizovat ji pomocí putState.
  • Při vytváření Účtu je volána funkce AddAccount, ve které je provedeno porovnání pro maximální počet účtů v blockchainu (maxAccounts = 5). A je tu zásek (všimli jste si?), Což vede k nekonečnému nárůstu počtu účtů. Takovým chybám je třeba se vyhnout

Dále načteme inteligentní smlouvu do kanálu a vytvoříme ji:

Blockchain: co bychom měli postavit PoC?

Podíváme se na transakci pro instalaci Smart Contract:

Blockchain: co bychom měli postavit PoC?

Podívejte se na podrobnosti o našem kanálu:

Blockchain: co bychom měli postavit PoC?

Výsledkem je následující schéma blockchainové sítě v cloudu IBM. Na diagramu je také ukázkový program běžící v cloudu Amazon na virtuálním serveru (podrobnosti o něm budou v další části):

Blockchain: co bychom měli postavit PoC?

Vytvoření GUI pro volání Hyperledger Fabric API

Hyperledger Fabric má API, které lze použít k:

  • Vytvořte kanál;
  • Peer připojení ke kanálu;
  • Instalace a konkretizace inteligentních smluv v kanálu;
  • Volací transakce;
  • Vyžádejte si informace o blockchainu.

Vývoj aplikací

V našem demo programu budeme API používat pouze k volání transakcí a vyžádání informací, protože. zbytek kroků jsme již provedli pomocí platformy IBM blockchain. Píšeme GUI pomocí standardního technologického zásobníku: Express.js + Vue.js + Node.js. O tom, jak začít s tvorbou moderních webových aplikací, můžete napsat samostatný článek. Zde zanechám odkaz na sérii přednášek, které se mi líbily nejvíce: Webová aplikace Full Stack pomocí Vue.js & Express.js. Výsledkem je aplikace klient-server se známým grafickým rozhraním ve stylu Material Designu Google. REST API mezi klientem a serverem se skládá z několika volání:

  • HyperledgerDemo/v1/init - inicializujte blockchain;
  • HyperledgerDemo/v1/accounts/list - získat seznam všech účtů;
  • HyperledgerDemo/v1/account?name=Bob&balance=100 - vytvořit účet Bob;
  • HyperledgerDemo/v1/info?account=Bob - získat informace o účtu Bob;
  • HyperledgerDemo/v1/transaction?from=Bob&to=Alice&volume=2 - převeďte dvě mince od Boba k Alici;
  • HyperledgerDemo/v1/disconnect – uzavře připojení k blockchainu.

Popis API s příklady Web pošťáka je známý program pro testování HTTP API.

Demo aplikace v cloudu Amazon

Aplikace byla nahrána na Amazon, protože IBM stále nedokázalo upgradovat můj účet a umožnit mi vytvářet virtuální servery. Jak byla doména připojena k třešni: www.citcoin.info. Nechám server chvíli zapnutý a pak ho vypnu, protože centy za pronájem odkapávají a citcoiny ještě nejsou na burze uvedeny) Do článku vkládám demo screenshoty, aby byla jasná logika práce. Demo aplikace může:

  • Inicializujte blockchain;
  • Vytvořte si účet (nyní však nelze vytvořit nový účet, protože v blockchainu bylo dosaženo maximálního počtu účtů uvedeného v chytré smlouvě);
  • Získejte seznam účtů;
  • Převádějte mince citcoinů mezi Alicí, Bobem a Alexem;
  • Přijímat události (nyní ale neexistuje způsob, jak události zobrazovat, takže pro zjednodušení je v rozhraní napsáno, že události nejsou podporovány);
  • Zaznamenat akce.

Nejprve inicializujeme blockchain:

Blockchain: co bychom měli postavit PoC?

Dále zahájíme náš účet, nezahrávejte si se zůstatkem:

Blockchain: co bychom měli postavit PoC?

Získáme seznam všech dostupných účtů:

Blockchain: co bychom měli postavit PoC?

Vybereme odesílatele a příjemce, získáme jejich zůstatky. Pokud jsou odesílatel a příjemce stejní, bude jeho účet doplněn:

Blockchain: co bychom měli postavit PoC?

V protokolu sledujeme provádění transakcí:

Blockchain: co bychom měli postavit PoC?

Ve skutečnosti, s demo programem, to je vše. Dále můžete vidět naši transakci v blockchainu:

Blockchain: co bychom měli postavit PoC?

A obecný seznam transakcí:

Blockchain: co bychom měli postavit PoC?

Tímto jsme úspěšně dokončili implementaci PoC pro vytvoření sítě Citcoin. Co dalšího je potřeba udělat, aby se z Citcoinu stala plnohodnotná síť pro převod mincí? Velmi málo:

  • Ve fázi vytváření účtu implementujte generování soukromého / veřejného klíče. Soukromý klíč musí být uložen uživatelským účtem, který je veřejný na blockchainu.
  • Proveďte převod mincí, ve kterém se k identifikaci uživatele nepoužívá jméno, ale veřejný klíč.
  • Šifrujte transakce od uživatele na server pomocí jeho soukromého klíče.

Závěr

Implementovali jsme síť Citcoin s následujícími funkcemi: přidání účtu, získání zůstatku, doplnění účtu, převod coinů z jednoho účtu na druhý. Co nás tedy stálo vybudování PoC?

  • Je nutné studovat blockchain obecně a Hyperledger Fabric zvláště;
  • Naučte se používat cloudy IBM nebo Amazon;
  • Naučte se programovací jazyk JS a nějaký webový rámec;
  • Pokud je potřeba některá data ukládat nikoli do blockchainu, ale do samostatné databáze, pak se naučte integrovat například s PostgreSQL;
  • A v neposlední řadě – bez znalosti Linuxu v moderním světě nikde!)

Samozřejmě, žádná raketová věda, ale zapotit se musíte!

Zdroje na GitHubu

Zdroje uvedeny GitHub. Stručný popis úložiště:
Katalog "Server» - Server Node.js
Katalog "zákazník» - Klient Node.js
Katalog "blockchain» (hodnoty parametrů a klíčů jsou samozřejmě nefunkční a jsou uvedeny pouze například):

  • contract — smart contract source
  • wallet – uživatelské klíče pro použití Hyperledger Fabric API.
  • *.cds - kompilované verze smart kontraktů
  • Soubory *.json – příklady konfiguračních souborů pro použití Hyperledger Fabric API

Je to jen začátek!

Zdroj: www.habr.com

Přidat komentář