Sytë friksohen, por duar janë të gatshme për punë!
Në artikujt e mëparshëm, ne u merem me teknologjitë mbi të cilat ndërtohen blockchain-et () dhe rastet e përdorimit që mund të realizohen me ndihmën e tyre (). Ka ardhur koha të punojmë me duar! Për realizimin e piloteve dhe PoC (Proof of Concept), unë preferoj të përdor re, pasi aksesin në to e kam nga çdo cep i botës, dhe shpesh nuk është nevoja të harxhoj kohë për instalimin e mjedisit, pasi ka konfiguracione të parapara. Pra, le të bëjmë diçka të thjeshtë, p.sh., një rrjet për transferimin e monedhave ndërmjet anëtarëve dhe ta quajmë modestisht Sytcoin. Për këtë do të përdorim re IBM dhe blockchain-in universale Hyperledger Fabric. Fillimisht, le të kuptojmë pse Hyperledger Fabric quhet një blockchain universal?

Hyperledger Fabric â blockchain universal
Në përgjithësi, një sistem informacioni universale është:
- Një grup serverash dhe një bërthamë programore që ekzekuton logjikën e biznesit;
- Interfazat për ndërveprim me sistemin;
- Mjetet për regjistrimin, autentifikimin dhe autorizimin e pajisjeve/njerezve;
- Një bazë të dhënash që ruan të dhënat operative dhe ato arkiv:

Mund të lexoni versionin zyrtar për atë çfarë është Hyperledger Fabric në , dhe nëse flasim shkurt, Hyperledger Fabric është një platformë opensource që lejon ndërtimin e blockchain-ve të mbyllur dhe ekzekutimin e kontratave inteligjente të shkruara në gjuhët programuese JS dhe Go. Le të shohim në detaje arkitekturën e Hyperledger Fabric dhe të konfirmojmë se është një sistem universal, ku ka vetëm specifika për ruajtjen dhe regjistrimin e të dhënave. Specifika qëndron në faktin se të dhënat, ashtu si në të gjitha blockchain-et, ruhen në blloqe, të cilat vendosen në blockchain vetëm kur pjesëmarrësit arrijnë një konsensus dhe pas regjistrimit, të dhënat nuk mund të korrigjohen ose fshihen pa u vënë re.
Arkitektura e Hyperledger Fabric
NĂ« diagram paraqitet arkitektura e Hyperledger Fabric:

Organizatat â organizatat pĂ«rmbajnĂ« peer, kĂ«shtu qĂ« blockchain-i ekziston pĂ«r shkak tĂ« mbĂ«shtetjes sĂ« organizatave. Organizata tĂ« ndryshme mund tĂ« pĂ«rfshihen nĂ« njĂ« kanal.
Kanal â njĂ« strukturĂ« logjike qĂ« bashkon peer nĂ« grupe, kĂ«shtu qĂ« pĂ«rcaktohet blockchain-i. Hyperledger Fabric mund tĂ« pĂ«rpunojĂ« njĂ«kohĂ«sisht disa blockchain-e me logjikĂ« tĂ« ndryshme biznesi.
Ofruesi i ShĂ«rbimeve tĂ« AnĂ«tarĂ«sisĂ« (MSP) â Ă«shtĂ« CA (Autoriteti i Certifikimit) pĂ«r lĂ«shimin e identitetit dhe caktimin e roleve. PĂ«r tĂ« krijuar njĂ« nod, duhet tĂ« bashkĂ«punoni me MSP.
NjĂ«si peer â kontrollojnĂ« transaksionet, ruajnĂ« blockchain, ekzekutojnĂ« kontrata inteligjente dhe ndihmojnĂ« aplikacionet. NjĂ«sitĂ« peer kanĂ« identitet (certifikatĂ« digjitale) qĂ« jepet nga MSP. Ndryshe nga rrjeti Bitcoin ose Ethereum, ku tĂ« gjitha nodet janĂ« tĂ« barabarta, nĂ« Hyperledger Fabric nodet luajnĂ« role tĂ« ndryshme:
- Njësi peer mund të jetë endorsing peer (EP) dhe të ekzekutojë kontrata inteligjente.
- Committing peer (CP) â ruajnĂ« vetĂ«m tĂ« dhĂ«nat nĂ« blockchain dhe pĂ«rditĂ«sojnĂ« "Statin e BotĂ«s".
- Anchor Peer (AP) â nĂ«se nĂ« blockchain marrin pjesĂ« disa organizata, atĂ«herĂ« ankor pĂ«r janĂ« pĂ«rdorur pĂ«r lidhjen midis tyre. Ădo organizatĂ« duhet tĂ« ketĂ« njĂ« ose disa ankor pĂ«r. Me ndihmĂ«n e AP, çdo peer nĂ« organizatĂ« mund tĂ« marrĂ« informacion rreth tĂ« gjithĂ« peer-ave nĂ« organizatat e tjera. PĂ«r tĂ« sinkronizuar informacionin midis AP pĂ«rdoret .
- Leader Peer â nĂ«se organizata ka disa peer, atĂ«herĂ« lideri peer do tĂ« marrĂ« blloqe nga shĂ«rbimi i porositjes dhe do t'i japĂ« ato pĂ«r peer-t e tjera. Lideri mund tĂ« vendoset nĂ« mĂ«nyrĂ« statike ose tĂ« zgjidhet dinamikisht nga peer-t nĂ« organizatĂ«. PĂ«r sinkronizimin e informacionit mbi liderĂ«t pĂ«rdoret gjithashtu protokolli gossip.
Aktivat â entitete me vlerĂ« qĂ« ruhen nĂ« bllokçen. MĂ« konkretisht â kjo Ă«shtĂ« tĂ« dhĂ«na key-value nĂ« formatin JSON. KĂ«to tĂ« dhĂ«na shkruhen nĂ« bllokçen "Blockchain". Ato kanĂ« histori qĂ« ruhet nĂ« bllokçen dhe njĂ« gjendje aktuale qĂ« ruhet nĂ« bazĂ«n e tĂ« dhĂ«nave "World state". Strukturat e tĂ« dhĂ«nave mbushen nĂ« mĂ«nyrĂ« tĂ« rastĂ«sishme nĂ« varĂ«si tĂ« detyrave tĂ« biznesit. Nuk ka asnjĂ« fushĂ« tĂ« detyrueshme, rekomandimi i vetĂ«m Ă«shtĂ« qĂ« asetet tĂ« kenĂ« pronar dhe tĂ« paraqesin vlerĂ«.
Ledger â pĂ«rbĂ«het nga bllokçena "Blockchain" dhe baza e tĂ« dhĂ«nave "World state", nĂ« tĂ« cilĂ«n ruhen gjendja aktuale e aseteve. World state pĂ«rdor LevelDB ose CouchDB.
Kontrata Smart â me kontratat smart realizohet logjika e biznesit tĂ« sistemit. NĂ« Hyperledger Fabric, kontratat smart quhen chaincode. NĂ«pĂ«rmjet chaincode pĂ«rcaktohen asset-et dhe transaksionet mbi to. NĂ« njĂ« term teknik, kontratat smart janĂ« module tĂ« programit, tĂ« realizuara nĂ« gjuhĂ«t e programimit JS ose Go.
Politika e miratimit â pĂ«r çdo chaincode mund tĂ« pĂ«rcaktohen politika se sa dhe nga kĂ« duhet tĂ« priten miratime pĂ«r transaksionin. NĂ«se politika nuk pĂ«rcaktohet, atĂ«herĂ« pĂ«rdoret si parazgjedhje: âtransaksioni duhet tĂ« miratohet nga çdo anĂ«tar (member) i çdo organizate nĂ« channelâ. Shembuj tĂ« politikave:
- Transaksioni duhet të miratohet nga një administrator i organizatës;
- Duhet të miratohet nga çdo anëtar (member) ose klient i organizatës;
- Duhet të miratohet nga çdo peer i organizatës.
ShĂ«rbimi i renditjes â paketat e transaksioneve nĂ« blloqe dhe i dĂ«rgon peer-ave nĂ« channel. Garanton dĂ«rgimin e mesazheve pĂ«r tĂ« gjithĂ« peer-at nĂ« rrjet. PĂ«r sistemet industriale pĂ«rdoret , pĂ«r zhvillim dhe testim .
Fluksi i thirrjeve

- Aplikacioni ndërvepron me Hyperledger Fabric, duke përdorur Go, Node.js ose Java SDK;
- Klienti krijon transaksionin tx dhe e dërgon atë te peer-at që miratojnë;
- Peer verifikon nënshkrimin e klientit, realizon transaksionin dhe dërgon nënshkrimin e miratimit përsëri tek klienti. Chaincode ekzekutohet vetëm në peer-in e miratimit, dhe rezultati i ekzekutimit të tij shpërndahet në të gjitha peer-at. Ky algoritëm funksionimi quhet - PBFT (Practical Byzantine Fault Tolerant) konsensus. Dallimi nga është se mesazhi dërgohet dhe pritet konfirmimi vetëm nga një grup i caktuar, jo nga të gjithë pjesëmarrësit;
- Pasi klienti të marrë numrin e përgjigjeve që korrespondon me politikën e miratimit, ai dërgon transaksionin në Ordering service;
- Ordering service formon bllokun dhe e dërgon atë tek të gjithë peer-at që angazhohen. Ordering service garanton regjistrimin në radhë të blloqeve, duke eliminuar, atë që quhet, ledger fork ();
- Peer-at marrin bllokun, kontrollojnë përsëri politikën e miratimit, regjistrojnë bllokun në blockchain dhe ndryshojnë gjendjen në DB-në "World state".
Pra, ndodh ndarja e rolit mes node-ve. Kjo siguron të shkallëzohet dhe sigurinë e blockchain-it:
- Kontratët e zgjuar (chaincode) ekzekutohen nga peer-at e miratimit. Kjo garanton konfidencialitetin e kontratave të zgjuara, pasi ato ruhen vetëm te peer-at e miratimit, jo te të gjithë pjesëmarrësit.
- Porositja duhet të funkcionalizojë shpejt. Kjo sigurohet nga fakti se Porositja formon vetëm bllokun dhe e dërgon atë në një grup të fiksur liderësh peers.
- Peers qĂ« e angazhojnĂ« vetĂ«m ruajnĂ« blockchain-in â ata mund tĂ« jenĂ« shumĂ« dhe nuk kĂ«rkojnĂ« fuqinĂ« e madhe dhe punĂ« tĂ« menjĂ«hershme.
Për më shumë detaje mbi zgjidhjet arkitekturore të Hyperledger Fabric dhe pse funksionon kështu, jo ndryshe, mund të shikoni këtu: ose këtu: .
Prandaj, Hyperledger Fabric është vërtet një sistem universale, me të cilin mund të:
- Implementoni logjikën e biznesit të rastit duke përdorur mekanizmin e kontratave të mençura;
- Regjistroni dhe merrni të dhëna nga databaza blockchain në formatin JSON;
- Siguroni dhe verifikoni qasje në API, duke përdorur Autoritetin e Certifikimit.
Tani që bëmë pak njohuri me specifikat e Hyperledger Fabric, le të bëjmë përfundimisht diçka të dobishme!
Zhvillojmë blockchain-in
Vendosja e detyrës
Qëllimi është të realizojë një rrjet Citcoin me funksionalitete si: krijimi i një llogarie, marrja e bilancit, mbushja e llogarisë, transferimi i monedhave nga një llogari në tjetrën. Do të vizatojmë një model objektiv, të cilin më pas do ta realizojmë në kontratën e zgjuar. Kështu, do të kemi llogari që identifikohen me emra (name) dhe kanë një bilanc (balance), si dhe një listë llogarish. Llogaritë dhe lista e llogarive janë në terma të Hyperledger Fabric asete. Prandaj, ato kanë një histori dhe një gjendje aktuale. Do të përpiqem ta tregoj këtë qartë:

Figurat e sipërme paraqesin gjendjen aktuale, e cila ruhet në bazën e të dhënave "World state". Nën to, figurat tregojnë historinë, e cila ruhet në blockchain. Gjendja aktuale e aseteve ndryshon nga transaksionet. Një aset ndryshohet vetëm në tërësi, prandaj pas përfundimit të transaksionit krijohet një objekt i ri, ndërsa vlera aktuale e aset-it kalon në histori.
Revoli i IBM
Krijojmë një llogari në . Për të përdorur platformën blockchain, duhet ta azhurnoni atë në Pay-As-You-Go. Ky proces nuk mund të jetë i shpejtë, pasi IBM kërkon informacion të mëtejshëm dhe e kontrollon atë manualisht. Pozitivisht, mund të them se IBM ofron materiale mjaft të mira mësimore që lejojnë implementimin e Hyperledger Fabric në cloud-in e tyre. Më pëlqeu seria e artikujve dhe shembujve të mëposhtëm:
Të dhënat në vijim janë shkëmbime nga platforma Blockchain e IBM. Kjo nuk është një udhëzues për krijimin e blockchain-it, por thjesht një demonstruese e vëllimit të detyrës. Prandaj, për qëllimet tona krijojmë një Organizatë:

Në të krijojmë node: Orderer CA, Org1 CA, Orderer Peer:

Vendosim përdorues:

Krijojmë Kanal dhe e quajmë citcoin:

Në thelb, Kanal është blockchain, prandaj fillon me bllokun zero (Genesis block):

Shkruajmë Kontratën e Mençur
/*
* 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;
Intuitivisht, këtu duhet të jetë gjithçka e kuptueshme:
- Ekzistojnë disa funksione (AddAccount, GetAccounts, SendFrom, GetBalance, RefillBalance), të cilat do të thërriten nga programi demo përmes API-t Hyperledger Fabric.
- Funksionet SendFrom dhe RefillBalance gjenerojnë ngjarje (Event), të cilat programi demo do t'i marrë.
- Funksioni instantiate â thirret njĂ«herĂ« kur instancohet kontrata e mençur. NĂ« tĂ« vĂ«rtetĂ«, ai nuk thirret njĂ«herĂ«, por çdo herĂ« kur ndodhin ndryshime nĂ« versionin e kontratĂ«s. Prandaj, inicializimi i listĂ«s me njĂ« array tĂ« zbrazĂ«t Ă«shtĂ« njĂ« ide e keqe, sepse tani kur ndryshojmĂ« versionin e kontratĂ«s sĂ« mençur, do tĂ« humbasim listĂ«n aktuale. Por asgjĂ«, unĂ« po mĂ«soj).
- Account-ët dhe lista e account-ëve (accounts) janë struktura të dhënash JSON. Përdoren JS për manipulimin e të dhënave.
- Vlerën aktuale të asset-it mund ta marrim duke thirrur funksionin getState dhe ta përditësojmë me putState.
- Gjatë krijimit të Account-it, thirret funksioni AddAccount, në të cilin bëhet krahasimi për numrin maksimal të account-ëve në blockchain (maxAccounts = 5). Dhe këtu ka një gabim (e vërejti?), që çon në rritjen e pafundme të numrit të account-ëve. Të tilla gabime duhet të shmangen)
Për më tepër, ngarkojmë kontratën e mençur në Channel dhe e instancojmë atë:

Shikojmë transaksionin për vendosjen e Smart Contract:

Shikojmë detajet për Channel-in tonë:

Si përfundim marrim këtë skemë të rrjetit blockchain në cloud të IBM. Po ashtu, në skemë ka një program demo, i cili funksionon në cloud të Amazon në një server virtual (do të flasim më shumë për të në seksionin e ardhshëm):

Krijimi i GUI për thirrjet e Hyperledger Fabric API
Hyperledger Fabric ka një API që mund të përdoret për:
- Krijimin e channel;
- Lidhjen e peer me channel;
- Installimin dhe instancimin e kontratave inteligjente në channel;
- Thirrjen e transaksioneve;
- Kërkimin e informacionit në blockchain.
Zhvillimi i aplikacionit
Në programin tonë demo do të përdorim API-në vetëm për thirrjen e transaksioneve dhe kërkimin e informacionit, pasi hapat e tjerë tashmë i kemi bërë, duke përdorur platformën blockchain të IBM. Po shkruajmë GUI, duke përdorur stakun e teknologjive standarde: Express.js + Vue.js + Node.js. Si të filloni të krijoni aplikacione moderne mund të shkruhet një artikull të veçantë. Këtu do të lë një lidhje me një seri ligjëratash që më pëlqen më shumë: . Si përfundim, u krijua një aplikacion klient-server me një ndërfaqe grafike të njohur në stilin Material Design nga Google. REST API midis klientit dhe serverit përbëhet nga disa thirrje:
- HyperledgerDemo/v1/init â inicializoni blockchain;
- HyperledgerDemo/v1/accounts/list â merrni njĂ« listĂ« tĂ« tĂ« gjithĂ« llogarive;
- HyperledgerDemo/v1/account?name=Bob&balance=100 â krijo llogarinĂ« Bob;
- HyperledgerDemo/v1/info?account=Bob â merr informacion rreth llogarisĂ« Bob;
- HyperledgerDemo/v1/transaction?from=Bob&to=Alice&volume=2 â transfero dy monedha nga Bob te Alice;
- HyperledgerDemo/v1/disconnect â mbyll lidhjen me blockchain-in.
PĂ«rshkrimi i API-sĂ« me shembuj e vendosa nĂ« â njĂ« program i njohur pĂ«r testimin e API-ve HTTP.
Aplikacioni demo në cloud-in e Amazon
E kam ngarkuar aplikacionin nĂ« Amazon, pasi IBM ende nuk ka arritur tĂ« pĂ«rmirĂ«sojĂ« llogarinĂ« time dhe tĂ« lejojĂ« krijimin e serverĂ«ve virtualĂ«. Si njĂ« qershi mbi tortĂ«, kam lidhur domenin: . Do ta mbaj pak serverin tĂ« aktivizuar, pastaj do ta çâaktivizoj, pasi koston pĂ«r qira po rritet, dhe monedhat citcoin nuk janĂ« ende tĂ« listuara nĂ« treg) NĂ« artikull do tĂ« pĂ«rfshij pamje tĂ« ekranit tĂ« demos, pĂ«r tĂ« shpjeguar logjikĂ«n e punĂ«s. Aplikacioni demo mund:
- Të inicializojë blockchain-in;
- Të krijojë llogari (por tani nuk mund të krijohet një llogari e re, pasi është arritur numri maksimal i llogarive që është përcaktuar në smart contract);
- Të marrë një listë të llogarive;
- Të transferojë monedha citcoin ndërmjet Alice, Bob dhe Alex;
- Merrni ngjarje (por tani ngjarjet nuk mund të shfaqen, ndaj për thjeshtësi në ndërfaqe është shkruar se ngjarjet nuk mbështeten);
- Regjistro veprimet.
Së pari, inicializojmë blockchain-in:

Më pas krijojmë llogarinë tonë, duke mos u kursyer me bilancin:

Merrni listën e të gjitha llogarive në dispozicion:

Zgjidhni dërguesin dhe marrësin, dhe merrni bilancet e tyre. Nëse dërguesi dhe marrësi janë i njëjti, atëherë do të ndodhi rimbushja e llogarisë së tij:

NĂ« log ndjekim realizimin e transaksioneve:

Në thelb, me programin demo është kjo e gjitha. Më pas mund të shihni transaksionin tonë në blockchain:

Dhe lista e përgjithshme e transaksioneve:

KĂ«shtu kemi pĂ«rfunduar me sukses realizimin e PoC pĂ«r krijimin e rrjetit Citcoin. ĂfarĂ« duhet bĂ«rĂ« mĂ« tej, qĂ« Citcoin tĂ« bĂ«het njĂ« rrjet i plotĂ« pĂ«r transferimin e monedhave? Paksa:
- NĂ« fazĂ«n e krijimit tĂ« llogarisĂ«, implementoni gjenerimin e çelĂ«sit privat / publik. ĂelĂ«si privat duhet tĂ« ruhet nga pĂ«rdoruesi i llogarisĂ«, çelĂ«si publik nĂ« blockchain.
- Bëni transferimin e monedhave, në të cilin identifikimi i përdoruesit bëhet me çelësin publik, jo me emrin.
- Kriptoni transaksionet që shkojnë nga përdoruesi në server me çelësin e tij privat.
Përfundimi
Ne kemi implementuar një rrjet Citcoin me funksione: shto llogari, merr balancën, mbush llogarinë tënde, transfero monedha nga një llogari në një tjetër. Pra, çfarë na kushtoi ndërtimi i PoC?
- Duhet të studiojmë blockchain-in në përgjithësi dhe Hyperledger Fabric në veçanti;
- Të mësojmë si të përdorim re të IBM ose Amazon;
- Të mësojmë gjuhën e programimit JS dhe ndonjë web framework;
- Nëse disa të dhëna duhet të ruhen jo në blockchain, por në një bazë të veçantë, atëherë të mësojmë si të integrohemi, për shembull, me PostgreSQL;
- Dhe e fundit nĂ« listĂ«, por jo mĂ« pak e rĂ«ndĂ«sishme â pa njohuri pĂ«r Linux nĂ« botĂ«n moderne nuk je askund!)
Sigurisht, nuk është rocket science, por do të duhet të punosh!
Burimet në GitHub
Burimet i kam vendosur në . Përshkrimi i shkurtër i depozitës:
Katalogu "server" â server Node.js
Katalogu "client" â klient Node.js
Katalogu "blockchain" (vlerat e parametrave dhe çelësat, natyrisht, nuk funksionojnë dhe jepen vetëm si shembuj):
- kontrata â burimi i smart kontratĂ«s
- wallet â çelĂ«sat e pĂ«rdoruesit pĂ«r tĂ« pĂ«rdorur Hyperledger Fabric API.
- *.cds â versionet e pĂ«rkthyera tĂ« smart kontratave
- *.json skedarĂ«t â shembuj tĂ« skedarĂ«ve tĂ« konfigurimit pĂ«r pĂ«rdorim me Hyperledger Fabric API
Kjo është vetëm fillimi!
Burimi: habr.com
