Blockchain: hvaða PoC ættum við að byggja?

Augun þín eru hrædd og hendurnar klæja!

Í fyrri greinum fjölluðum við um tæknina sem blockchains eru byggðar á (Hvað ættum við að byggja blockchain?) og mál sem hægt er að útfæra með hjálp þeirra (Af hverju ættum við að byggja mál?). Það er kominn tími til að vinna með höndunum! Til að innleiða flugmenn og PoC (Proof of Concept) vil ég frekar nota skýin, því... hægt er að nálgast þær hvar sem er í heiminum og oft er engin þörf á að eyða tíma í leiðinlega uppsetningu á umhverfinu, því Það eru forstilltar stillingar. Svo, við skulum gera eitthvað einfalt, til dæmis, net til að flytja mynt á milli þátttakenda og við skulum kalla það hóflega Bitcoin. Til þess munum við nota IBM skýið og alhliða blockchain Hyperledger Fabric. Í fyrsta lagi skulum við reikna út hvers vegna Hyperledger Fabric er kallað alhliða blockchain?

Blockchain: hvaða PoC ættum við að byggja?

Hyperledger Fabric - alhliða blockchain

Almennt séð er alhliða upplýsingakerfi:

  • Set af netþjónum og hugbúnaðarkjarna sem framkvæmir viðskiptarökfræði;
  • Tengi fyrir samskipti við kerfið;
  • Verkfæri fyrir skráningu, auðkenningu og heimild tækja/fólks;
  • Gagnagrunnur sem geymir rekstrar- og geymslugögn:

Blockchain: hvaða PoC ættum við að byggja?

Opinberu útgáfuna af því hvað Hyperledger Fabric er má lesa á Online, og í stuttu máli, Hyperledger Fabric er opinn uppspretta vettvangur sem gerir þér kleift að byggja upp einkablokkakeðjur og framkvæma handahófskennda snjalla samninga skrifaða á JS og Go forritunarmálunum. Við skulum skoða ítarlega arkitektúr Hyperledger Fabric og ganga úr skugga um að þetta sé alhliða kerfi sem hefur aðeins sérstöðu til að geyma og skrá gögn. Sérstaðan er sú að gögnin, eins og í öllum blockchains, eru geymd í blokkum sem eru settar á blockchain aðeins ef þátttakendur ná samstöðu og eftir skráningu er ekki hægt að leiðrétta eða eyða gögnunum hljóðlega.

Hyperledger Fabric Architecture

Skýringarmyndin sýnir Hyperledger Fabric arkitektúrinn:

Blockchain: hvaða PoC ættum við að byggja?

Félög — samtök innihalda jafningja, þ.e. blockchain er til vegna stuðnings stofnana. Mismunandi stofnanir geta verið hluti af sömu rásinni.

Sund — rökrétt uppbygging sem sameinar jafningja í hópa, þ.e. blockchain er tilgreint. Hyperledger Fabric getur unnið úr mörgum blockchains samtímis með mismunandi viðskiptarökfræði.

Aðildarþjónusta (MSP) er CA (Certificate Authority) til að gefa út auðkenni og úthluta hlutverkum. Til að búa til hnút þarftu að hafa samskipti við MSP.

Jafningjahnútar - staðfesta viðskipti, geyma blockchain, framkvæma snjalla samninga og hafa samskipti við forrit. Jafnaldrar hafa auðkenni (stafrænt vottorð), sem er gefið út af MSP. Ólíkt Bitcoin eða Etherium netinu, þar sem allir hnútar hafa jafnan rétt, gegna Hyperledger Fabric hnúðar mismunandi hlutverkum:

  • Jafningur kannski styður jafningja (EP) og framkvæma snjalla samninga.
  • Skuldbindandi jafningi (CP) - vistaðu aðeins gögn í blockchain og uppfærðu „heimsríkið“.
  • Akkeri Peer (AP) - ef nokkrar stofnanir taka þátt í blockchain, þá eru akkeri jafningjar notaðir til samskipta á milli þeirra. Hver stofnun verður að hafa einn eða fleiri akkeri jafningja. Með því að nota AP geta allir jafningjar í stofnun fengið upplýsingar um alla jafningja í öðrum stofnunum. Notað til að samstilla upplýsingar á milli AP slúðursamskiptareglur.
  • Leiðtogi Peer — ef stofnun hefur nokkra jafningja, þá mun aðeins leiðtogi jafningjans fá blokkir frá pöntunarþjónustunni og gefa þeim hinum jafningjunum. Leiðtoginn getur annað hvort verið tilgreindur með kyrrstöðu eða valinn á kraftmikinn hátt af jafningjum í stofnuninni. Slúðursamskiptareglur eru einnig notaðar til að samstilla upplýsingar um leiðtoga.

Eignir - einingar sem hafa gildi og eru geymdar á blockchain. Nánar tiltekið eru þetta lykilgildisgögn á JSON sniði. Það eru þessi gögn sem eru skráð í Blockchain. Þeir hafa sögu, sem er geymd í blockchain, og núverandi ástand, sem er geymt í „World State“ gagnagrunninum. Gagnaskipulag er fyllt út af geðþótta eftir viðskiptaverkefnum. Það eru engir nauðsynlegir reitir, eina ráðleggingin er að eignir verða að eiga eiganda og vera verðmætar.

Ledger — samanstendur af Blockchain og Word ástandsgagnagrunninum, sem geymir núverandi stöðu eigna. Heimsríki notar LevelDB eða CouchDB.

Snjall samningur — með því að nota snjalla samninga er viðskiptarökfræði kerfisins útfærð. Í Hyperledger Fabric eru snjallir samningar kallaðir keðjukóði. Með því að nota keðjukóða eru eignir og viðskipti yfir þær tilgreindar. Tæknilega séð eru snjallsamningar hugbúnaðareiningar útfærðar á JS eða Go forritunarmálunum.

Áritunarstefna — fyrir hvern keðjukóða er hægt að setja stefnu um hversu margar staðfestingar fyrir viðskipti á að búast við og frá hverjum. Ef stefnan er ekki stillt, þá er sjálfgefið: „viðskiptin verða að vera staðfest af hvaða meðlimi hvaða stofnunar sem er á rásinni.“ Dæmi um stefnur:

  • Viðskiptin verða að vera samþykkt af hvaða stjórnanda stofnunarinnar sem er;
  • Verður að vera staðfest af einhverjum meðlimum eða viðskiptavinum samtakanna;
  • Verður að vera staðfest af hvaða jafningjastofnun sem er.

Pöntunarþjónusta - pakkar færslum í blokkir og sendir til jafningja á rásinni. Tryggir afhendingu skilaboða til allra jafningja á netinu. Notað fyrir iðnaðarkerfi Kafka skilaboðamiðlari, til þróunar og prófunar Single.

CallFlow

Blockchain: hvaða PoC ættum við að byggja?

  • Forritið hefur samskipti við Hyperledger Fabric með því að nota Go, Node.js eða Java SDK;
  • Viðskiptavinurinn býr til tx viðskipti og sendir hana til samþykkis jafningja;
  • Jafningurinn sannreynir undirskrift viðskiptavinarins, lýkur viðskiptunum og sendir áritunarundirskriftina til baka til viðskiptavinarins. Keðjukóði er aðeins keyrður á jafningja sem samþykkir, og niðurstaðan af framkvæmd hans er send til allra jafningja. Þetta reiknirit vinnunnar er kallað PBFT (Practical Byzantine Fault Tolerant) samstaða. Frábrugðið klassískt BFT sú staðreynd að skilaboðin eru send og búist er við staðfestingu ekki frá öllum þátttakendum, heldur aðeins frá ákveðnu setti;
  • Eftir að viðskiptavinurinn hefur fengið þann fjölda svara sem samsvarar áritunarstefnunni sendir hann færsluna til pöntunarþjónustunnar;
  • Pöntunarþjónustan býr til blokk og sendir hana til allra skuldbundinna jafningja. Pöntunarþjónusta tryggir raðskráningu á blokkum, sem útilokar svokallaðan höfuðbókargafl (sjá kaflann "Gafflar");
  • Jafnaldrar fá blokk, athugaðu meðmælisstefnuna aftur, skrifaðu blokkina í blokkakeðjuna og breyttu ástandinu í „Heimsríki“ DB.

Þeir. Þetta leiðir til hlutverkaskiptingar milli hnútanna. Þetta tryggir að blockchain sé stigstærð og örugg:

  • Snjallir samningar (keðjukóði) framkvæma samþykki jafningja. Þetta tryggir trúnað um snjalla samninga, vegna þess að það er ekki geymt af öllum þátttakendum, heldur aðeins með því að samþykkja jafningja.
  • Pöntun ætti að virka hratt. Þetta er tryggt með því að Ordering myndar aðeins blokk og sendir það til ákveðins hóps leiðtogafélaga.
  • Skuldbindandi jafningjar geyma aðeins blockchain - þeir geta verið margir og þeir þurfa ekki mikið afl og tafarlausa notkun.

Nánari upplýsingar um byggingarlausnir Hyperledger Fabric og hvers vegna það virkar á þennan hátt en ekki annað má finna hér: Uppruni byggingarlistar eða hér: Hyperledger Fabric: Dreift stýrikerfi fyrir leyfilegar blokkakeðjur.

Svo, Hyperledger Fabric er sannarlega alhliða kerfi sem þú getur:

  • Innleiða handahófskennda viðskiptarökfræði með því að nota snjallsamningakerfið;
  • Taktu upp og taktu á móti gögnum úr blockchain gagnagrunninum á JSON sniði;
  • Veittu og staðfestu API aðgang með því að nota vottunaryfirvöld.

Nú þegar við skiljum svolítið um sérstöðu Hyperledger Fabric, skulum við loksins gera eitthvað gagnlegt!

Að dreifa blockchain

Samsetning vandans

Verkefnið er að innleiða Citcoin netið með eftirfarandi aðgerðum: búa til reikning, fá jafnvægi, fylla á reikninginn þinn, flytja mynt frá einum reikningi til annars. Við skulum teikna hlutlíkan sem við munum útfæra frekar í snjallsamningi. Þannig að við munum hafa reikninga sem eru auðkenndir með nöfnum og innihalda stöðu og lista yfir reikninga. Reikningar og listi yfir reikninga eru, hvað varðar Hyperledger Fabric eignir. Í samræmi við það hafa þeir sögu og núverandi ástand. Ég skal reyna að teikna þetta skýrt:

Blockchain: hvaða PoC ættum við að byggja?

Efstu tölurnar eru núverandi ástand, sem er geymt í „World state“ gagnagrunninum. Fyrir neðan þær eru tölur sem sýna söguna sem er geymd í blockchain. Núverandi staða eigna er breytt með viðskiptum. Eignin breytist aðeins í heild sinni, þannig að vegna viðskiptanna verður nýr hlutur til og núverandi verðmæti eignarinnar fer í sögu.

IBM Cloud

Við búum til reikning í IBM ský. Til að nota blockchain vettvanginn verður að uppfæra hann í Pay-As-You-Go. Þetta ferli er kannski ekki fljótlegt vegna þess að... IBM biður um viðbótarupplýsingar og staðfestir þær handvirkt. Á jákvæðu nótunum get ég sagt að IBM er með gott þjálfunarefni sem gerir þér kleift að dreifa Hyperledger Fabric í skýinu sínu. Mér líkaði eftirfarandi röð greina og dæma:

Eftirfarandi eru skjámyndir af IBM Blockchain pallinum. Þetta er ekki leiðbeining um hvernig á að búa til blockchain, heldur einfaldlega sýning á umfangi verkefnisins. Svo, í okkar tilgangi, búum við til eina stofnun:

Blockchain: hvaða PoC ættum við að byggja?

Við búum til hnúta í því: Orderer CA, Org1 CA, Orderer Peer:

Blockchain: hvaða PoC ættum við að byggja?

Við búum til notendur:

Blockchain: hvaða PoC ættum við að byggja?

Búðu til rás og kallaðu það citcoin:

Blockchain: hvaða PoC ættum við að byggja?

Í meginatriðum er Channel blockchain, svo það byrjar á blokk núll (Genesis blokk):

Blockchain: hvaða PoC ættum við að byggja?

Að skrifa snjöllan samning

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

Innsæi ætti allt að vera skýrt hér:

  • Það eru nokkrar aðgerðir (AddAccount, GetAccounts, SendFrom, GetBalance, RefillBalance) sem kynningarforritið mun kalla með Hyperledger Fabric API.
  • SendFrom og RefillBalance aðgerðirnar búa til atburði sem kynningarforritið mun fá.
  • Staðfestingaraðgerðin er kölluð einu sinni þegar snjallsamningur er sýndur. Reyndar er það kallað ekki bara einu sinni, heldur í hvert skipti sem snjallsamningsútgáfan breytist. Þess vegna er slæm hugmynd að frumstilla lista með tómu fylki, vegna þess að Nú, þegar við breytum útgáfu snjallsamningsins, munum við missa núverandi lista. En það er allt í lagi, ég er bara að læra).
  • Reikningar og listi yfir reikninga eru JSON gagnaskipulag. JS er notað til að vinna með gögn.
  • Þú getur fengið núverandi verðmæti eignar með því að nota getState fallkallið og uppfært það með putState.
  • Þegar reikningur er stofnaður er kallað á AddAccount aðgerðina, þar sem samanburður er gerður fyrir hámarksfjölda reikninga í blockchain (maxAccounts = 5). Og hér er jamb (hefurðu tekið eftir?), sem leiðir til endalausrar fjölgunar reikninga. Slík mistök ber að forðast)

Næst hleðum við snjallsamningnum inn á rásina og birtum hann:

Blockchain: hvaða PoC ættum við að byggja?

Við skulum skoða viðskiptin til að setja upp Smart Contract:

Blockchain: hvaða PoC ættum við að byggja?

Við skulum skoða smáatriðin um rásina okkar:

Blockchain: hvaða PoC ættum við að byggja?

Fyrir vikið fáum við eftirfarandi skýringarmynd af blockchain neti í IBM skýinu. Skýringarmyndin sýnir einnig kynningarforrit sem keyrir í Amazon skýinu á sýndarþjóni (meira um það í næsta kafla):

Blockchain: hvaða PoC ættum við að byggja?

Að búa til GUI fyrir Hyperledger Fabric API símtöl

Hyperledger Fabric er með API sem hægt er að nota til að:

  • Búa til rás;
  • Tengingar jafningja í rás;
  • Uppsetning og staðfesting á snjöllum samningum í rásinni;
  • Símtöl;
  • Biðja um upplýsingar um blockchain.

Umsókn þróun

Í kynningarforritinu okkar munum við aðeins nota API til að hringja í viðskipti og biðja um upplýsingar, vegna þess að Við höfum þegar lokið þeim skrefum sem eftir eru með því að nota IBM blockchain vettvang. Við skrifum GUI með því að nota staðlaðan tæknistafla: Express.js + Vue.js + Node.js. Þú getur skrifað sérstaka grein um hvernig á að byrja að búa til nútíma vefforrit. Hér mun ég skilja eftir hlekk á þá fyrirlestraröð sem mér líkaði best við: Full Stack Web App með Vue.js & Express.js. Niðurstaðan er biðlara-miðlaraforrit með kunnuglegu grafísku viðmóti í efnishönnunarstíl Google. REST API milli biðlara og netþjóns samanstendur af nokkrum símtölum:

  • HyperledgerDemo/v1/init - frumstilla blockchain;
  • HyperledgerDemo/v1/accounts/list — fáðu lista yfir alla reikninga;
  • HyperledgerDemo/v1/account?name=Bob&balance=100 — búa til Bob reikning;
  • HyperledgerDemo/v1/info?account=Bob — fáðu upplýsingar um Bob reikning;
  • HyperledgerDemo/v1/transaction?from=Bob&to=Alice&volume=2 — flytja tvær mynt frá Bob til Alice;
  • HyperledgerDemo/v1/disconnect - lokaðu tengingunni við blockchain.

Lýsing á API með dæmum innifalin í Heimasíða Postman - vel þekkt forrit til að prófa HTTP API.

Kynningarforrit í Amazon skýi

Ég hlóð forritinu upp á Amazon vegna þess að... IBM hefur enn ekki getað uppfært reikninginn minn og leyft mér að búa til sýndarþjóna. Hvernig á að bæta kirsuber við lénið: www.citcoin.info. Ég mun halda netþjóninum kveiktum í smá stund og slökkva svo á honum vegna þess að... sent til leigu eru að lækka og citcoin mynt er ekki enn skráð í kauphöllinni) Ég læt skjáskot af kynningunni fylgja með í greininni svo rökfræði verksins sé skýr. Sýningarforritið getur:

  • Frumstilla blockchain;
  • Búðu til reikning (en nú geturðu ekki búið til nýjan reikning vegna þess að hámarksfjöldi reikninga sem tilgreindur er í snjallsamningnum hefur verið náð í blockchain);
  • Fáðu lista yfir reikninga;
  • Flyttu citcoin mynt á milli Alice, Bob og Alex;
  • Fáðu viðburði (en nú er engin leið til að sýna viðburði, svo til einföldunar segir viðmótið að atburðir séu ekki studdir);
  • Skráðu aðgerðir.

Fyrst frumstillum við blockchain:

Blockchain: hvaða PoC ættum við að byggja?

Næst búum við til reikninginn okkar, ekki eyða tíma í stöðuna:

Blockchain: hvaða PoC ættum við að byggja?

Við fáum lista yfir alla tiltæka reikninga:

Blockchain: hvaða PoC ættum við að byggja?

Við veljum sendanda og viðtakanda og fáum stöður þeirra. Ef sendandi og viðtakandi eru sá sami, verður reikningur hans endurnýjaður:

Blockchain: hvaða PoC ættum við að byggja?

Í skránni fylgjumst við með framkvæmd viðskipta:

Blockchain: hvaða PoC ættum við að byggja?

Reyndar er þetta allt með kynningarforritinu. Hér að neðan geturðu séð viðskipti okkar í blockchain:

Blockchain: hvaða PoC ættum við að byggja?

Og almennur listi yfir viðskipti:

Blockchain: hvaða PoC ættum við að byggja?

Með þessu höfum við lokið innleiðingu PoC til að búa til Citcoin netið með góðum árangri. Hvað þarf annað að gera til að Citcoin verði fullbúið net til að flytja mynt? Mjög lítið:

  • Á stigi stofnunar reiknings skaltu innleiða myndun einka-/opinber lykils. Einkalykillinn verður að vera geymdur hjá reikningsnotandanum, opinberi lykillinn verður að vera geymdur í blockchain.
  • Gerðu myntflutning þar sem opinber lykill, frekar en nafn, er notaður til að auðkenna notandann.
  • Dulkóða viðskipti sem fara frá notanda til netþjóns með einkalykli hans.

Ályktun

Við höfum innleitt Citcoin netið með eftirfarandi aðgerðum: bæta við reikningi, fá stöðu, fylla á reikninginn þinn, flytja mynt frá einum reikningi til annars. Svo, hvað kostaði það okkur að smíða PoC?

  • Þú þarft að læra blockchain almennt og Hyperledger Fabric sérstaklega;
  • Lærðu að nota IBM eða Amazon ský;
  • Lærðu JS forritunarmálið og einhvern veframma;
  • Ef einhver gögn þarf að geyma ekki í blockchain, heldur í sérstökum gagnagrunni, lærðu þá að samþætta, til dæmis með PostgreSQL;
  • Og síðast en ekki síst - þú getur ekki lifað í nútíma heimi án þekkingar á Linux!)

Auðvitað eru það ekki eldflaugavísindi, en þú verður að vinna hörðum höndum!

Heimildir á GitHub

Heimildir settar á GitHub. Stutt lýsing á geymslunni:
Vörulisti «miðlara» — Node.js netþjónn
Vörulisti «viðskiptavinur» — Node.js viðskiptavinur
Vörulisti «blockchain"(færibreytugildi og lyklar, að sjálfsögðu, virka ekki og eru aðeins gefin sem dæmi):

  • samningur — frumkóði snjallsamnings
  • veski — notendalyklar til að nota Hyperledger Fabric API.
  • *.cds - samsettar útgáfur af snjöllum samningum
  • *.json skrár - dæmi um stillingarskrár til að nota Hyperledger Fabric API

Það er aðeins byrjunin!

Heimild: www.habr.com

Bæta við athugasemd