Korábbi cikkeinkben foglalkoztunk azokkal a technológiákkal, amelyekre a blokkláncok épülnek (Mit építsünk blokkláncot?) és a segítségükkel megvalósítható esetek (Miért építsünk ügyet?). Itt az ideje, hogy a kezeddel dolgozz! A pilotok és a PoC (Proof of Concept) megvalósításához inkább a felhőket használom, mert... a világ bármely pontjáról elérhetők, és gyakran nem kell időt vesztegetni a környezet unalmas telepítésére, mert Vannak előre beállított konfigurációk. Tehát készítsünk valami egyszerűt, például egy hálózatot a résztvevők közötti érmék átvitelére, és szerényen nevezzük Bitcoinnak. Ehhez az IBM felhőt és az univerzális blokkláncot, a Hyperledger Fabric-et fogjuk használni. Először is nézzük meg, miért nevezik a Hyperledger Fabric-et univerzális blokkláncnak?
Hyperledger Fabric - univerzális blokklánc
Általánosságban elmondható, hogy egy univerzális információs rendszer:
Szerverkészlet és egy üzleti logikát végrehajtó szoftvermag;
Interfészek a rendszerrel való interakcióhoz;
Eszközök az eszközök/személyek regisztrációjához, hitelesítéséhez és engedélyezéséhez;
Működési és archív adatokat tároló adatbázis:
A Hyperledger Fabric hivatalos verziója itt olvasható Online, és röviden, a Hyperledger Fabric egy nyílt forráskódú platform, amely lehetővé teszi privát blokkláncok építését és tetszőleges, JS és Go programozási nyelveken írt intelligens szerződések végrehajtását. Nézzük meg részletesen a Hyperledger Fabric architektúráját, és győződjön meg arról, hogy ez egy univerzális rendszer, amely csak az adatok tárolására és rögzítésére szolgál. A sajátosság az, hogy az adatokat, mint minden blokkláncnál, blokkokban tárolják, amelyek csak akkor kerülnek a blokkláncra, ha a résztvevők konszenzusra jutnak, és a rögzítés után az adatokat nem lehet csendben javítani vagy törölni.
Hyperledger Fabric Architecture
A diagram a Hyperledger Fabric architektúrát mutatja:
Szervezetek — a szervezetek társakat tartalmaznak, pl. A blokklánc a szervezetek támogatásának köszönhetően létezik. Különböző szervezetek lehetnek ugyanannak a csatornának a részei.
csatorna — a társakat csoportokba tömörítő logikai struktúra, pl. a blokklánc meg van adva. A Hyperledger Fabric egyszerre több különböző üzleti logikával rendelkező blokkláncot tud feldolgozni.
Tagsági szolgáltató (MSP) egy CA (Certificate Authority) az identitás kiadására és a szerepek kiosztására. Csomópont létrehozásához kapcsolatba kell lépnie az MSP-vel.
Peer csomópontok — tranzakciók ellenőrzése, blokklánc tárolása, intelligens szerződések végrehajtása és alkalmazásokkal való interakció. A partnerek azonosítóval (digitális tanúsítvánnyal) rendelkeznek, amelyet az MSP bocsát ki. Ellentétben a Bitcoin vagy az Etherium hálózattal, ahol minden csomópont egyenlő jogokkal rendelkezik, a Hyperledger Fabric-ben a csomópontok különböző szerepet töltenek be:
Talán egyenrangú támogató társ (EP) és intelligens szerződések végrehajtása.
Elkötelezett társ (CP) - csak az adatokat mentse el a blokkláncban, és frissítse a „világállapotot”.
Anchor Peer (AP) - ha több szervezet vesz részt a blokkláncban, akkor a köztük lévő kommunikációhoz horgonytársakat használnak. Minden szervezetnek rendelkeznie kell egy vagy több horgonytárssal. Az AP használatával a szervezet bármely partnere információkat szerezhet a többi szervezet összes társáról. Az AP-k közötti információk szinkronizálására szolgál pletykaprotokoll.
Vezető Peer — ha egy szervezetnek több társtársa van, akkor csak a partner vezetője kap blokkokat a Megrendelő szolgáltatástól és adja át a többi társnak. A vezetőt statikusan meghatározhatják, vagy dinamikusan kiválaszthatják a szervezet munkatársai. A pletykaprotokollt a vezetőkről szóló információk szinkronizálására is használják.
Eszközök — olyan entitások, amelyeknek van értéke és a blokkláncon tárolódnak. Pontosabban, ezek kulcsérték adatok JSON formátumban. Ezeket az adatokat rögzíti a Blockchain. Van egy előzményük, amelyet a blokkláncban tárolnak, és egy aktuális állapotuk, amelyet a „World state” adatbázisban tárolnak. Az adatstruktúrák az üzleti feladatoktól függően tetszőlegesen töltődnek ki. Nincsenek kötelező mezők, az egyetlen javaslat az, hogy az eszközöknek legyen tulajdonosa és értékesnek kell lenniük.
Főkönyv — a Blockchain és a Word állapotadatbázisból áll, amely az eszközök aktuális állapotát tárolja. A világállam a LevelDB-t vagy a CouchDB-t használja.
Okos szerződés — okos szerződések segítségével valósul meg a rendszer üzleti logikája. A Hyperledger Fabricban az intelligens szerződéseket lánckódnak nevezik. A lánckód segítségével meghatározzák az eszközöket és a rajtuk lévő tranzakciókat. Technikai értelemben az intelligens szerződések JS vagy Go programozási nyelveken implementált szoftvermodulok.
Jóváhagyási politika — minden lánckódhoz beállíthat egy szabályzatot arra vonatkozóan, hogy egy tranzakcióhoz hány visszaigazolást kell várni és kitől. Ha a házirend nincs beállítva, akkor az alapértelmezett: „a tranzakciót a csatornán lévő bármely szervezet bármely tagjának meg kell erősítenie.” Példák az irányelvekre:
A tranzakciót a szervezet bármely rendszergazdájának jóvá kell hagynia;
A szervezet bármely tagjának vagy ügyfelének meg kell erősítenie;
Bármely társszervezetnek meg kell erősítenie.
Rendelési szolgáltatás — blokkokba csomagolja a tranzakciókat, és elküldi azokat a csatornán lévő társaknak. Garantálja az üzenetek kézbesítését a hálózat összes társához. Ipari rendszerekhez használják Kafka üzenetközvetítő, fejlesztésre és tesztelésre Egyetlen.
CallFlow
Az alkalmazás Go, Node.js vagy Java SDK használatával kommunikál a Hyperledger Fabric-cal;
Az ügyfél létrehoz egy tx-tranzakciót, és elküldi a támogató partnereknek;
A Peer ellenőrzi az ügyfél aláírását, befejezi a tranzakciót, és visszaküldi a jóváhagyó aláírást az ügyfélnek. A lánckódot csak a jóváhagyó peer hajtja végre, és a végrehajtás eredményét elküldi az összes társnak. Ezt a munkaalgoritmust PBFT (Practical Byzantine Fault Tolerant) konszenzusnak nevezik. Eltér klasszikus BFT az a tény, hogy az üzenetet elküldik, és a megerősítést nem minden résztvevőtől, hanem csak egy bizonyos csoporttól várják;
Miután az ügyfél megkapta a jóváhagyási szabályzatnak megfelelő számú választ, elküldi a tranzakciót a Megrendelő szolgáltatásnak;
A Rendelési szolgáltatás blokkot generál, és elküldi az összes elkötelezett partnernek. A rendelési szolgáltatás biztosítja a blokkok szekvenciális rögzítését, ami kiküszöböli az ún.lásd a "Villa" részt);
A társak blokkot kapnak, újra ellenőrzik a jóváhagyási szabályzatot, írják a blokkot a blokkláncba, és módosítják az állapotot a „World state” DB-ben.
Azok. Ez a csomópontok közötti szereposztáshoz vezet. Ez biztosítja, hogy a blokklánc méretezhető és biztonságos legyen:
Az intelligens szerződések (lánckód) jóváhagyó partnereket hajtanak végre. Ez biztosítja az intelligens szerződések titkosságát, mert nem minden résztvevő tárolja, hanem csak jóváhagyó társak.
A rendelésnek gyorsan kell működnie. Ezt az a tény biztosítja, hogy a Rendelés csak egy blokkot képez, és azt elküldi a vezetőtársak rögzített halmazának.
Az elkötelezett társak csak a blokkláncot tárolják - sok lehet belőlük, és nem igényelnek nagy energiát és azonnali működést.
Tehát a Hyperledger Fabric egy igazán univerzális rendszer, amellyel:
Tetszőleges üzleti logika megvalósítása az intelligens szerződési mechanizmus segítségével;
Adatok rögzítése és fogadása a blokklánc adatbázisból JSON formátumban;
Adjon meg és ellenőrizze az API-hozzáférést a tanúsító hatóság segítségével.
Most, hogy egy kicsit megértjük a Hyperledger Fabric sajátosságait, végre tegyünk valami hasznosat!
Blokklánc telepítése
Probléma nyilatkozat
A feladat a Citcoin hálózat megvalósítása a következő funkciókkal: számla létrehozása, egyenleg beszerzése, számla feltöltése, érmék átvitele egyik számláról a másikra. Rajzoljunk egy objektummodellt, amit egy intelligens szerződésben fogunk tovább implementálni. Tehát olyan számláink lesznek, amelyeket nevek azonosítanak, és tartalmaznak egyenleget, valamint egy listát a számlákról. A számlák és a számlák listája a Hyperledger Fabric eszközök szempontjából. Ennek megfelelően van történelmük és jelenlegi állapotuk. Megpróbálom világosan lerajzolni:
A legfelső számok az aktuális állapotot mutatják, amelyet a „World state” adatbázisban tárolunk. Alatta ábrák a blokkláncban tárolt előzményeket mutatják. Az eszközök jelenlegi állapotát a tranzakciók változtatják. Az Eszköz csak egészében változik, így a tranzakció eredményeként új objektum jön létre, és az eszköz aktuális értéke bekerül a történelembe.
IBM Cloud
fiókot hozunk létre IBM felhő. A blokklánc platform használatához frissíteni kell Pay-As-You-Go-ra. Ez a folyamat nem biztos, hogy gyors, mert... Az IBM további információkat kér, és azokat manuálisan ellenőrzi. Pozitívumként elmondhatom, hogy az IBM jó oktatóanyagokkal rendelkezik, amelyek lehetővé teszik a Hyperledger Fabric telepítését a felhőjükben. Az alábbi cikkek és példák tetszettek:
Az alábbiakban az IBM Blockchain platform képernyőképei láthatók. Ez nem egy blokklánc létrehozására vonatkozó utasítás, hanem egyszerűen a feladat hatókörének bemutatása. Tehát céljaink érdekében létrehozunk egy szervezetet:
Csomópontokat hozunk létre benne: Rendelő CA, Org1 CA, Megrendelő Peer:
Felhasználókat hozunk létre:
Hozz létre egy csatornát, és hívd citcoinnak:
A Channel lényegében egy blokklánc, tehát a nulla blokkkal kezdődik (Genesis blokk):
Okos szerződés írása
/*
* 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;
Intuitív módon itt mindennek világosnak kell lennie:
Számos funkció (AddAccount, GetAccounts, SendFrom, GetBalance, RefillBalance) létezik, amelyeket a bemutató program meghív a Hyperledger Fabric API segítségével.
A SendFrom és RefillBalance funkciók eseményeket generálnak, amelyeket a demóprogram fog kapni.
A példányosítási funkciót egyszer hívják meg, amikor egy intelligens szerződést példányosítanak. Valójában nem csak egyszer hívják meg, hanem minden alkalommal, amikor az intelligens szerződéses verzió változik. Ezért egy listát üres tömbbel inicializálni rossz ötlet, mert Most, amikor megváltoztatjuk az intelligens szerződés verzióját, elveszítjük az aktuális listát. De nem baj, még csak tanulok).
A fiókok és a fiókok listája JSON-adatstruktúrák. A JS-t adatkezelésre használják.
Egy eszköz aktuális értékét a getState függvényhívás segítségével kaphatja meg, és a putState segítségével frissítheti.
Fiók létrehozásakor meghívásra kerül az AddAccount függvény, amelyben összehasonlítás történik a blokkláncban található fiókok maximális számával (maxAccounts = 5). És itt van egy jamb (észrevetted?), ami a fiókok számának végtelen növekedéséhez vezet. Az ilyen hibákat el kell kerülni)
Ezután betöltjük az intelligens szerződést a csatornába, és példányosítjuk:
Nézzük meg a Smart Contract telepítésének tranzakcióját:
Nézzük a részleteket csatornánkkal kapcsolatban:
Ennek eredményeként a következő diagramot kapjuk egy blokklánc hálózatról az IBM felhőben. Az ábrán egy virtuális szerveren futó Amazon felhőben futó bemutató program is látható (erről bővebben a következő részben):
GUI létrehozása Hyperledger Fabric API-hívásokhoz
A Hyperledger Fabric rendelkezik egy API-val, amely a következőkre használható:
Csatorna létrehozása;
Egyenrangú kapcsolatok;
Intelligens szerződések telepítése és példányosítása a csatornában;
Lehívási tranzakciók;
Kérjen információt a blokkláncról.
Alkalmazásfejlesztés
Demó programunkban az API-t csak tranzakciók lehívására és információk kérésére használjuk, mert A hátralévő lépéseket már elvégeztük az IBM blokklánc platform használatával. GUI-t írunk egy szabványos technológiai verem segítségével: Express.js + Vue.js + Node.js. A modern webalkalmazások létrehozásának megkezdéséről külön cikket írhat. Itt hagyok egy linket a számomra leginkább tetsző előadássorozathoz: Full Stack webalkalmazás Vue.js és Express.js használatával. Az eredmény egy kliens-szerver alkalmazás, ismerős grafikus felülettel a Google Material Design stílusában. A kliens és a szerver közötti REST API több hívásból áll:
HyperledgerDemo/v1/init - inicializálja a blokkláncot;
HyperledgerDemo/v1/accounts/list — az összes fiók listája;
HyperledgerDemo/v1/info?account=Bob — információkat kaphat a Bob-fiókról;
HyperledgerDemo/v1/transaction?from=Bob&to=Alice&volume=2 - két érme átvitele Bobtól Alice-hez;
HyperledgerDemo/v1/disconnect – zárja be a kapcsolatot a blokklánccal.
Az API leírása a következő példákkal Postás weboldal - egy jól ismert program a HTTP API tesztelésére.
Demo alkalmazás az Amazon felhőben
Azért töltöttem fel az alkalmazást az Amazonra, mert... Az IBM még mindig nem tudta frissíteni a fiókomat, és lehetővé tenni virtuális szerverek létrehozását. Hogyan adjunk hozzá egy cseresznyét a domainhez: www.citcoin.info. Egy ideig bekapcsolva tartom a szervert, aztán kikapcsolom, mert... csöpögnek a bérleti centek, a citcoin érméket pedig még nem jegyzik a tőzsdén) A cikkben a demóról készült screenshotokat mellékelem, hogy a munka logikája egyértelmű legyen. A demo alkalmazás:
Inicializálja a blokkláncot;
Fiók létrehozása (de most nem hozhat létre új fiókot, mert a blokkláncban elérte az intelligens szerződésben meghatározott maximális fiókszámot);
Megkapja a fiókok listáját;
Vigyen át citcoin érméket Alice, Bob és Alex között;
Események fogadása (de most nincs mód az események megjelenítésére, így az egyszerűség kedvéért a felület azt írja, hogy az események nem támogatottak);
Napló műveletek.
Először inicializáljuk a blokkláncot:
Ezután létrehozzuk fiókunkat, ne vesztegessük az időt az egyenleggel:
Kapunk egy listát az összes elérhető fiókról:
Kiválasztjuk a feladót és a címzettet, és megkapjuk az egyenlegüket. Ha a feladó és a címzett ugyanaz, akkor fiókja feltöltésre kerül:
A naplóban figyeljük a tranzakciók végrehajtását:
Valójában ez minden a demo programmal. Alább láthatja tranzakciónkat a blokkláncban:
És a tranzakciók általános listája:
Ezzel sikeresen befejeztük a PoC megvalósítását a Citcoin hálózat létrehozásához. Mit kell még tenni ahhoz, hogy a Citcoin teljes értékű érmék átadási hálózattá váljon? Nagyon kevés:
A fiók létrehozásának szakaszában hajtsa végre a privát / nyilvános kulcs generálását. A privát kulcsot a fiók felhasználójánál, a nyilvános kulcsot a blokkláncban kell tárolni.
Készítsen érmeátutalást, amelyben név helyett nyilvános kulcsot használnak a felhasználó azonosítására.
Titkosítja a felhasználótól a szerverhez tartó tranzakciókat a saját privát kulcsával.
Következtetés
A Citcoin hálózatot a következő funkciókkal hoztuk létre: számla hozzáadása, egyenleg beszerzése, számla feltöltése, érmék átvitele egyik számláról a másikra. Szóval mennyibe került egy PoC építése?
Tanulmányoznia kell a blokkláncot általában, és különösen a Hyperledger Fabric-et;
Tanulja meg az IBM vagy az Amazon felhők használatát;
Tanulja meg a JS programozási nyelvet és néhány webes keretrendszert;
Ha bizonyos adatokat nem a blokkláncban, hanem egy külön adatbázisban kell tárolni, akkor tanulj meg integrálni például a PostgreSQL-lel;
És végül, de nem utolsósorban: a modern világban nem lehet Linux ismerete nélkül élni!)
Természetesen ez nem rakétatudomány, de keményen kell dolgoznod!
Források a GitHubon
Források fel GitHub. Az adattár rövid leírása:
Katalógus «szerver» — Node.js szerver
Katalógus «vásárló» — Node.js kliens
Katalógus «blockchain"(a paraméterértékek és a kulcsok természetesen nem működnek, és csak példaként szerepelnek):
szerződés — intelligens szerződés forráskódja
pénztárca — felhasználói kulcsok a Hyperledger Fabric API használatához.