{"id":37868,"date":"2019-10-31T22:20:16","date_gmt":"2019-10-31T19:20:16","guid":{"rendered":"https:\/\/prohoster.info\/blog\/blokchejn-chto-nam-stoit-poc-postroit\/"},"modified":"2019-10-31T22:20:16","modified_gmt":"2019-10-31T19:20:16","slug":"blokchejn-chto-nam-stoit-poc-postroit","status":"publish","type":"post","link":"https:\/\/prohoster.info\/cs\/blog\/administrirovanie\/blokchejn-chto-nam-stoit-poc-postroit","title":{"rendered":"Blockchain: co n\u00e1s stoj\u00ed postavit PoC?","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><i>O\u010di se boj\u00ed, ale ruce se t\u011b\u0161\u00ed!<\/i><\/p>\n<p>V p\u0159edchoz\u00edch \u010dl\u00e1nc\u00edch jsme se pod\u00edvali na technologie, na kter\u00fdch se blockchainy stav\u00ed (<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/443282\/\">Co n\u00e1s stoj\u00ed postavit blockchain?<\/a><\/noindex>) a na p\u0159\u00edpady pou\u017eit\u00ed, kter\u00e9 lze s jejich pomoc\u00ed realizovat (<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/449986\/\">Co n\u00e1s stoj\u00ed postavit p\u0159\u00edpad?<\/a><\/noindex>). Nastal \u010das d\u00e1t ruce k d\u00edlu! Pro realizaci pilot\u016f a PoC (Proof of Concept) preferuji pou\u017e\u00edvat cloud, proto\u017ee k nim je p\u0159\u00edstup odkudkoli na sv\u011bt\u011b a \u010dasto nen\u00ed t\u0159eba ztr\u00e1cet \u010das nudnou instalac\u00ed prost\u0159ed\u00ed, proto\u017ee existuj\u00ed p\u0159edinstalovan\u00e9 konfigurace. Tak\u017ee si ud\u011blejme n\u011bco jednoduch\u00e9ho, nap\u0159\u00edklad s\u00ed\u0165 pro p\u0159evod minc\u00ed mezi \u00fa\u010dastn\u00edky a nazveme ji skromn\u011b Citcoin. K tomu pou\u017eijeme cloud IBM a univerz\u00e1ln\u00ed blockchain Hyperledger Fabric. Nejprve si objasn\u00edme, pro\u010d se Hyperledger Fabric naz\u00fdv\u00e1 univerz\u00e1ln\u00edm blockchainem?<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: co n\u00e1s stoj\u00ed postavit PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/c19278d99d5b7edb9f50ea6306c2fd46.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>Hyperledger Fabric \u2014 univerz\u00e1ln\u00ed blockchain<\/h2>\n<p>\nObecn\u011b \u0159e\u010deno, univerz\u00e1ln\u00ed informa\u010dn\u00ed syst\u00e9m je:<\/p>\n<ul>\n<li>Soubor server\u016f a programov\u00e9 j\u00e1dro vykon\u00e1vaj\u00edc\u00ed obchodn\u00ed logiku;<\/li>\n<li>Rozhran\u00ed pro interakci se syst\u00e9mem;<\/li>\n<li>Prost\u0159edky pro registraci, autentizaci a autorizaci za\u0159\u00edzen\u00ed\/ lid\u00ed;<\/li>\n<li>Datab\u00e1ze uchov\u00e1vaj\u00edc\u00ed operativn\u00ed a archivn\u00ed data:<\/li>\n<\/ul>\n<p>\n<img decoding=\"async\" alt=\"Blockchain: co n\u00e1s stoj\u00ed postavit PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/f11fe73de54b0573d44fae903d367df9.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nOfici\u00e1ln\u00ed verzi o tom, co je Hyperledger Fabric, lze p\u0159e\u010d\u00edst na <noindex><a rel=\"nofollow\" href=\"https:\/\/www.hyperledger.org\">webu<\/a><\/noindex>, a pokud to shrneme, tak Hyperledger Fabric je open-source platforma, kter\u00e1 umo\u017e\u0148uje vytv\u00e1\u0159et uzav\u0159en\u00e9 blockchainy a prov\u00e1d\u011bt libovoln\u00e9 chytr\u00e9 smlouvy napsan\u00e9 v programovac\u00edch jazyc\u00edch JS a Go. Pod\u00edvejme se podrobn\u011b na architekturu Hyperledger Fabric a p\u0159esv\u011bd\u010dme se, \u017ee se jedn\u00e1 o univerz\u00e1ln\u00ed syst\u00e9m, ve kter\u00e9m je pouze specifika ohledn\u011b ukl\u00e1d\u00e1n\u00ed a z\u00e1pisu dat. Specifika spo\u010d\u00edvaj\u00ed v tom, \u017ee data, stejn\u011b jako ve v\u0161ech blockchainov\u00fdch syst\u00e9mech, jsou uchov\u00e1v\u00e1na v bloc\u00edch, kter\u00e9 jsou zahrnuty do blockchainu pouze pokud \u00fa\u010dastn\u00edci dos\u00e1hli konsenzu a po z\u00e1pisu nelze data nen\u00e1padn\u011b opravit nebo odstranit.<\/p>\n<h2>Architektura Hyperledger Fabric<\/h2>\n<p>\nNa sch\u00e9matu je zn\u00e1zorn\u011bna architektura Hyperledger Fabric:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: co n\u00e1s stoj\u00ed postavit PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/7488d70b330af2bbae1db67005f22a3e.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<b>Organizations <\/b> \u2014 organizace obsahuj\u00ed peer-y, t\u00edm p\u00e1dem blockchain existuje d\u00edky podpo\u0159e organizac\u00ed. R\u016fzn\u00e9 organizace mohou pat\u0159it do jednoho kan\u00e1lu.<\/p>\n<p><b>Channel <\/b> \u2014 logick\u00e1 struktura, kter\u00e1 spojuje peer-y do skupin, \u010d\u00edm\u017e se upravuje blockchain. Hyperledger Fabric m\u016f\u017ee sou\u010dasn\u011b zpracov\u00e1vat n\u011bkolik blockchain\u016f s r\u016fznou obchodn\u00ed logikou.<\/p>\n<p><b>Membership Services Provider (MSP)<\/b> \u2014 je CA (Certificate Authority) pro vyd\u00e1v\u00e1n\u00ed identity a p\u0159id\u011blov\u00e1n\u00ed rol\u00ed. Pro vytvo\u0159en\u00ed uzlu je pot\u0159eba komunikovat s MSP.<\/p>\n<p><b>Peer uzly<\/b> \u2014 ov\u011b\u0159uj\u00ed transakce, uchov\u00e1vaj\u00ed blockchain, vykon\u00e1vaj\u00ed chytr\u00e9 smlouvy a interaguj\u00ed s aplikacemi. Peery maj\u00ed identitu (digit\u00e1ln\u00ed certifik\u00e1t), kter\u00fd vyd\u00e1v\u00e1 MSP. Na rozd\u00edl od s\u00edt\u011b Bitcoin nebo Ethereum, kde jsou v\u0161echny uzly rovnocenn\u00e9, v Hyperledger Fabric uzly hraj\u00ed r\u016fzn\u00e9 role:<\/p>\n<ul>\n<li>Peer m\u016f\u017ee b\u00fdt <b>endorsing peer<\/b> (EP) a vykon\u00e1vat chytr\u00e9 smlouvy.<\/li>\n<li><b>Committing peer<\/b> (CP) \u2014 pouze ukl\u00e1daj\u00ed data do blockchainu a aktualizuj\u00ed \u201eWorld state\u201c.<\/li>\n<li><b>Anchor Peer<\/b> (AP) \u2014 pokud se na blockchainu pod\u00edl\u00ed v\u00edce organizac\u00ed, pou\u017e\u00edvaj\u00ed se anchor peery pro komunikaci mezi nimi. Ka\u017ed\u00e1 organizace mus\u00ed m\u00edt jeden nebo v\u00edce anchor peer\u016f. Pomoc\u00ed AP m\u016f\u017ee jak\u00fdkoli peer v organizaci z\u00edskat informace o v\u0161ech peer\u00e1ch v jin\u00fdch organizac\u00edch. Pro synchronizaci informac\u00ed mezi AP se pou\u017e\u00edv\u00e1 <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Gossip_protocol\">gossip protokol<\/a><\/noindex>.<\/li>\n<li><b>Leader Peer<\/b> \u2014 pokud organizace m\u00e1 v\u00edce peer\u016f, pouze leader peer bude p\u0159ij\u00edmat bloky z Ordering service a p\u0159ed\u00e1vat je ostatn\u00edm peer\u016fm. Leader m\u016f\u017ee b\u00fdt ur\u010den staticky nebo vyb\u00edr\u00e1n dynamicky peerami v organizaci. Pro synchronizaci informac\u00ed o v\u016fdc\u00edch se tak\u00e9 pou\u017e\u00edv\u00e1 gossip protokol.<\/li>\n<\/ul>\n<p>\n<b>Aktiva <\/b> \u2014 entity, kter\u00e9 maj\u00ed hodnotu a jsou uchov\u00e1v\u00e1ny v blockchainu. P\u0159esn\u011bji \u0159e\u010deno \u2014 to jsou key-value data ve form\u00e1tu JSON. Tyto \u00fadaje jsou vlastn\u011b zapisov\u00e1ny do blockchainu \u201eBlockchain\u201c. Maj\u00ed historii, kter\u00e1 je uchov\u00e1v\u00e1na v blockchainu, a aktu\u00e1ln\u00ed stav, kter\u00fd se uchov\u00e1v\u00e1 v datab\u00e1zi \u201eWorld state\u201c. Datov\u00e9 struktury jsou vypl\u0148ov\u00e1ny podle obchodn\u00edch pot\u0159eb. Neexistuj\u00ed \u017e\u00e1dn\u00e1 povinn\u00e1 pole, jedin\u00fdm doporu\u010den\u00edm je, \u017ee aktiva by m\u011bla m\u00edt vlastn\u00edka a p\u0159edstavovat hodnotu. <\/p>\n<p><b>Kniha <\/b> \u2014 skl\u00e1d\u00e1 se z blockchainu \u201eBlockchain\u201c a datab\u00e1ze \u201eWorld state\u201c, ve kter\u00e9 je uchov\u00e1v\u00e1n aktu\u00e1ln\u00ed stav aktiv. World state pou\u017e\u00edv\u00e1 LevelDB nebo CouchDB.<\/p>\n<p><b>Chytr\u00e1 smlouva<\/b> \u2014 pomoc\u00ed chytr\u00fdch smluv se realizuje obchodn\u00ed logika syst\u00e9mu. V Hyperledger Fabric se chytr\u00e9 smlouvy naz\u00fdvaj\u00ed chaincode. Pomoc\u00ed chaincode se definuj\u00ed aktiva a transakce s nimi. Technicky \u0159e\u010deno, chytr\u00e9 smlouvy jsou programov\u00e9 moduly realizovan\u00e9 v programovac\u00edch jazyc\u00edch JS nebo Go.<\/p>\n<p><b>Politika schv\u00e1len\u00ed<\/b> \u2014 pro ka\u017ed\u00fd chaincode lze definovat politiky, kolik a od koho je t\u0159eba o\u010dek\u00e1vat potvrzen\u00ed pro transakci. Pokud politika nen\u00ed stanovena, plat\u00ed v\u00fdchoz\u00ed nastaven\u00ed: \u201etransakci mus\u00ed potvrdit libovoln\u00fd \u010dlen (member) jak\u00e9koli organizace v channel\u201c. P\u0159\u00edklady politik:<\/p>\n<ul>\n<li>Transakci by m\u011bl potvrdit kter\u00fdkoli administr\u00e1tor organizace;<\/li>\n<li>Mus\u00ed potvrdit kter\u00fdkoli \u010dlen (member) nebo klient organizace;<\/li>\n<li>Mus\u00ed potvrdit kter\u00fdkoli peer organizace.<\/li>\n<\/ul>\n<p>\n<b>Slu\u017eba objedn\u00e1v\u00e1n\u00ed<\/b> \u2014 shroma\u017e\u010fuje transakce do blok\u016f a odes\u00edl\u00e1 je peer\u016fm v channel. Zaji\u0161\u0165uje doru\u010den\u00ed zpr\u00e1v v\u0161em peer\u016fm v s\u00edti. Pro pr\u016fmyslov\u00e9 syst\u00e9my se pou\u017e\u00edv\u00e1 <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/Apache_Kafka\">zpr\u00e1vov\u00fd broker Kafka<\/a><\/noindex>, pro v\u00fdvoj a testov\u00e1n\u00ed <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/hyperledger\/fabric\/tree\/master\/orderer\/consensus\/solo\">Solo<\/a><\/noindex>.<\/p>\n<h2>CallFlow<\/h2>\n<p>\n<img decoding=\"async\" alt=\"Blockchain: co n\u00e1s stoj\u00ed postavit PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/9060864bd1002da881d7f17ef8ec0b0c.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<ul>\n<li>Aplikace interaguje s Hyperledger Fabric pomoc\u00ed Go, Node.js nebo Java SDK;<\/li>\n<li>Klient vytv\u00e1\u0159\u00ed transakci tx a pos\u00edl\u00e1 ji na endorsing peery;<\/li>\n<li>Peer kontroluje podpis klienta, prov\u00e1d\u00ed transakci a odes\u00edl\u00e1 endorsement signature zp\u011bt klientovi. Chaincode se prov\u00e1d\u00ed pouze na endorsing peer, a v\u00fdsledek jeho proveden\u00ed je rozesl\u00e1n v\u0161em peer\u016fm. Tento algoritmus se naz\u00fdv\u00e1 \u2014 PBFT (Practical Byzantine Fault Tolerant) konsensus. Li\u0161\u00ed se od <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Byzantine_fault\">klasick\u00e9ho BFT<\/a><\/noindex> t\u00edm, \u017ee zpr\u00e1va se rozes\u00edl\u00e1 a potvrzen\u00ed se o\u010dek\u00e1v\u00e1 nejen od v\u0161ech \u00fa\u010dastn\u00edk\u016f, ale pouze od ur\u010dit\u00e9ho souboru;<\/li>\n<li>Jakmile klient obdr\u017e\u00ed po\u010det odpov\u011bd\u00ed odpov\u00eddaj\u00edc\u00ed politice endorsement, ode\u0161le transakci na slu\u017ebu objedn\u00e1v\u00e1n\u00ed;<\/li>\n<li>Slu\u017eba objedn\u00e1v\u00e1n\u00ed vytv\u00e1\u0159\u00ed blok a pos\u00edl\u00e1 ho v\u0161em committing peer\u016fm. Slu\u017eba objedn\u00e1v\u00e1n\u00ed zaji\u0161\u0165uje sekven\u010dn\u00ed z\u00e1znam blok\u016f, co\u017e vylu\u010duje takzvan\u00fd ledger fork (<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/443282\/\">viz \u010d\u00e1st \u201eForky\u201c<\/a><\/noindex>);<\/li>\n<li>Peery obdr\u017e\u00ed blok, znovu zkontroluj\u00ed politiku endorsement, zap\u00ed\u0161\u00ed blok do blockchainu a zm\u011bn\u00ed stav v datab\u00e1zi \u201eWorld state\u201c.<\/li>\n<\/ul>\n<p>\nT\u00edm se dos\u00e1hne rozd\u011blen\u00ed rol\u00ed mezi uzly. To zaji\u0161\u0165uje \u0161k\u00e1lovatelnost a bezpe\u010dnost blockchainu:<\/p>\n<ul>\n<li>Chytr\u00e9 kontrakty (chaincode) prov\u00e1d\u011bj\u00ed endorsing peery. To zaji\u0161\u0165uje d\u016fv\u011brnost chytr\u00fdch kontrakt\u016f, proto\u017ee se neuchov\u00e1vaj\u00ed u v\u0161ech \u00fa\u010dastn\u00edk\u016f, ale pouze na endorsing peer\u00e1ch.<\/li>\n<li>Objedn\u00e1v\u00e1n\u00ed mus\u00ed fungovat rychle. To je zaji\u0161t\u011bno t\u00edm, \u017ee objedn\u00e1v\u00e1n\u00ed pouze vytv\u00e1\u0159\u00ed blok a odes\u00edl\u00e1 ho na pevn\u011b stanovenou skupinu leader peer\u016f.<\/li>\n<li>Committing peery pouze uchov\u00e1vaj\u00ed blockchain \u2014 m\u016f\u017ee jich b\u00fdt mnoho a nepot\u0159ebuj\u00ed velkou v\u00fdkonovou kapacitu ani okam\u017eitou odezvu. <\/li>\n<\/ul>\n<p>\nPodrobn\u011bji se o architektonick\u00fdch \u0159e\u0161en\u00edch Hyperledger Fabric a pro\u010d funguje tak, jak funguje, lze pod\u00edvat zde: <noindex><a rel=\"nofollow\" href=\"https:\/\/hyperledger-fabric.readthedocs.io\/en\/latest\/arch-deep-dive.html\">Architektonick\u00e9 p\u016fvody<\/a><\/noindex> nebo zde: <noindex><a rel=\"nofollow\" href=\"https:\/\/arxiv.org\/abs\/1801.10228v2\">Hyperledger Fabric: Distribuovan\u00fd opera\u010dn\u00ed syst\u00e9m pro povolen\u00e9 blockchainy<\/a><\/noindex>.<\/p>\n<p>Hyperledger Fabric je skute\u010dn\u011b univerz\u00e1ln\u00ed syst\u00e9m, kter\u00fd umo\u017e\u0148uje:<\/p>\n<ul>\n<li>Implementovat libovolnou obchodn\u00ed logiku pomoc\u00ed mechanismu chytr\u00fdch kontrakt\u016f;<\/li>\n<li>Zapisovat a z\u00edsk\u00e1vat data z blockchainov\u00e9 datab\u00e1ze ve form\u00e1tu JSON;<\/li>\n<li>Poskytovat a ov\u011b\u0159ovat p\u0159\u00edstup k API pomoc\u00ed certifika\u010dn\u00ed autority. <\/li>\n<\/ul>\n<p>\nNyn\u00ed, kdy\u017e jsme si trochu vyjasnili specifika Hyperledger Fabric, poj\u010fme kone\u010dn\u011b ud\u011blat n\u011bco u\u017eite\u010dn\u00e9ho!<\/p>\n<h2>Nasazen\u00ed blockchainu<\/h2>\n<p><\/p>\n<h3>Formulace \u00fakolu<\/h3>\n<p>\n\u00dakolem je realizovat s\u00ed\u0165 Citcoin, kter\u00e1 bude m\u00edt n\u00e1sleduj\u00edc\u00ed funkce: vytvo\u0159it \u00fa\u010det, z\u00edskat z\u016fstatek, dob\u00edt \u00fa\u010det, p\u0159ev\u00e9st mince z jednoho \u00fa\u010dtu na druh\u00fd. Nakresl\u00edme objektov\u00fd model, kter\u00fd pak implementujeme v chytr\u00e9m kontraktu. Budeme m\u00edt \u00fa\u010dty, kter\u00e9 budou identifikov\u00e1ny jm\u00e9ny (name) a obsahovat z\u016fstatek (balance), a seznam \u00fa\u010dt\u016f. \u00da\u010dty a seznam \u00fa\u010dt\u016f jsou v terminologii Hyperledger Fabric aktiva. Maj\u00ed tedy historii a aktu\u00e1ln\u00ed stav. Pokus\u00edm se to n\u00e1zorn\u011b zn\u00e1zornit:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: co n\u00e1s stoj\u00ed postavit PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/a4f111da59bc7982b51d583857db6d5a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nHorn\u00ed figurky p\u0159edstavuj\u00ed aktu\u00e1ln\u00ed stav, kter\u00fd je ulo\u017een v datab\u00e1zi \u201eWorld state\u201c. Pod nimi jsou figurky zobrazuj\u00edc\u00ed historii, kter\u00e1 je ulo\u017eena v blockchainu. Aktu\u00e1ln\u00ed stav aktiv se m\u011bn\u00ed transakcemi. Aktivum se m\u011bn\u00ed pouze jako celek, proto se po vykon\u00e1n\u00ed transakce vytvo\u0159\u00ed nov\u00fd objekt a aktu\u00e1ln\u00ed hodnota aktiva se p\u0159esune do historie. <\/p>\n<h3>IBM Cloud <\/h3>\n<p>\nZalo\u017ete si \u00fa\u010det v <noindex><a rel=\"nofollow\" href=\"https:\/\/cloud.ibm.com\">IBM cloudu<\/a><\/noindex>. Aby bylo mo\u017en\u00e9 pou\u017e\u00edvat blockchainovou platformu, je nutn\u00e9 ji upgradovat na model Pay-As-You-Go. Tento proces m\u016f\u017ee trvat d\u00e9le, proto\u017ee IBM vy\u017eaduje dal\u0161\u00ed informace a prov\u00e1d\u00ed jejich ru\u010dn\u00ed kontrolu. Na pozitivn\u00ed stran\u011b mohu \u0159\u00edci, \u017ee IBM m\u00e1 dobr\u00e9 vzd\u011bl\u00e1vac\u00ed materi\u00e1ly, kter\u00e9 umo\u017e\u0148uj\u00ed nasadit Hyperledger Fabric v jejich cloudu. L\u00edbil se mi n\u00e1sleduj\u00edc\u00ed cyklus \u010dl\u00e1nk\u016f a p\u0159\u00edklad\u016f:<\/p>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/IBM\/Create-BlockchainNetwork-IBPV20\/blob\/master\/README.md\">Vytvo\u0159te z\u00e1kladn\u00ed blockchainovou s\u00ed\u0165 pomoc\u00ed Blockchain Platformy<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/IBM\/SmartContractTrading-wFabric1-4-VSCodeExt\/blob\/master\/README.md\">Vytvo\u0159te a spus\u0165te chytr\u00fd kontrakt na blockchainu<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/IBM\/auction-events\/blob\/master\/README.md\">Emitujte ud\u00e1losti z Blockchain Platformy<\/a><\/noindex><\/li>\n<\/ul>\n<p>\nN\u00e1sleduj\u00ed screenshoty Blockchainov\u00e9 platformy IBM. Toto nen\u00ed n\u00e1vod k vytvo\u0159en\u00ed blockchainu, ale pouze uk\u00e1zka rozsahu \u00fakolu. Pro na\u0161e \u00fa\u010dely vytvo\u0159\u00edme jednu organizaci:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: co n\u00e1s stoj\u00ed postavit PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/7cb30cade6315abc69f4322a2dbcd094.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nV n\u00ed vytvo\u0159\u00edme uzly: Orderer CA, Org1 CA, Orderer Peer:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: co n\u00e1s stoj\u00ed postavit PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/4a2239a9b7ded8ba5a11ffad86a35094.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nZalo\u017e\u00edme u\u017eivatele:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: co n\u00e1s stoj\u00ed postavit PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/6792b12c9316f47b0cdfaf771dacc782.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nVytvo\u0159\u00edme kan\u00e1l a pojmenujeme ho citcoin:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: co n\u00e1s stoj\u00ed postavit PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/ea3983f209326713dcd25762c348ac96.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nV podstat\u011b je kan\u00e1l blockchain, tak\u017ee za\u010d\u00edn\u00e1 nulov\u00fdm blokem (Genesis block):<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: co n\u00e1s stoj\u00ed postavit PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/416df6b6ef832c6550a2642592e57250.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h3>Nap\u00ed\u0161eme chytr\u00fd kontrakt<\/h3>\n<p><\/p>\n<pre><code class=\"javascript\">\/*\n * Citcoin smart-contract v1.5 for Hyperledger Fabric\n * (c) Alexey Sushkov, 2019\n *\/\n \n'use strict';\n \nconst { Contract } = require('fabric-contract-api');\nconst maxAccounts = 5;\n \nclass CitcoinEvents extends Contract {\n \n    async instantiate(ctx) {\n        console.info('instantiate');\n        let emptyList = [];\n        await ctx.stub.putState('accounts', Buffer.from(JSON.stringify(emptyList)));\n    }\n    \/\/ Get all accounts\n    async GetAccounts(ctx) {\n        \/\/ Get account list:\n        let accounts = '{}'\n        let accountsData = await ctx.stub.getState('accounts');\n        if (accountsData) {\n            accounts = JSON.parse(accountsData.toString());\n        } else {\n            throw new Error('accounts not found');\n        }\n        return accountsData.toString()\n    }\n     \/\/ add a account object to the blockchain state identifited by their name\n    async AddAccount(ctx, name, balance) {\n        \/\/ this is account data:\n        let account = {\n            name: name,\n            balance: Number(balance),       \n            type: 'account',\n        };\n        \/\/ create account:\n        await ctx.stub.putState(name, Buffer.from(JSON.stringify(account)));\n \n        \/\/ Add account to list:\n        let accountsData = await ctx.stub.getState('accounts');\n        if (accountsData) {\n            let accounts = JSON.parse(accountsData.toString());\n            if (accounts.length &lt; maxAccounts)\n            {\n                accounts.push(name);\n                await ctx.stub.putState('accounts', Buffer.from(JSON.stringify(accounts)));\n            } else {\n                throw new Error('Max accounts number reached');\n            }\n        } else {\n            throw new Error('accounts not found');\n        }\n        \/\/ return  object\n        return JSON.stringify(account);\n    }\n    \/\/ Sends money from Account to Account\n    async SendFrom(ctx, fromAccount, toAccount, value) {\n        \/\/ get Account from\n        let fromData = await ctx.stub.getState(fromAccount);\n        let from;\n        if (fromData) {\n            from = JSON.parse(fromData.toString());\n            if (from.type !== 'account') {\n                throw new Error('wrong from type');\n            }   \n        } else {\n            throw new Error('Accout from not found');\n        }\n        \/\/ get Account to\n        let toData = await ctx.stub.getState(toAccount);\n        let to;\n        if (toData) {\n            to = JSON.parse(toData.toString());\n            if (to.type !== 'account') {\n                throw new Error('wrong to type');\n            }  \n        } else {\n            throw new Error('Accout to not found');\n        }\n \n        \/\/ update the balances\n        if ((from.balance - Number(value)) &gt;= 0 ) {\n            from.balance -= Number(value);\n            to.balance += Number(value);\n        } else {\n            throw new Error('From Account: not enought balance');          \n        }\n \n        await ctx.stub.putState(from.name, Buffer.from(JSON.stringify(from)));\n        await ctx.stub.putState(to.name, Buffer.from(JSON.stringify(to)));\n                 \n        \/\/ define and set Event\n        let Event = {\n            type: \"SendFrom\",\n            from: from.name,\n            to: to.name,\n            balanceFrom: from.balance,\n            balanceTo: to.balance,\n            value: value\n        };\n        await ctx.stub.setEvent('SendFrom', Buffer.from(JSON.stringify(Event)));\n \n        \/\/ return to object\n        return JSON.stringify(from);\n    }\n \n    \/\/ get the state from key\n    async GetState(ctx, key) {\n        let data = await ctx.stub.getState(key);\n        let jsonData = JSON.parse(data.toString());\n        return JSON.stringify(jsonData);\n    }\n    \/\/ GetBalance   \n    async GetBalance(ctx, accountName) {\n        let data = await ctx.stub.getState(accountName);\n        let jsonData = JSON.parse(data.toString());\n        return JSON.stringify(jsonData);\n    }\n     \n    \/\/ Refill own balance\n    async RefillBalance(ctx, toAccount, value) {\n        \/\/ get Account to\n        let toData = await ctx.stub.getState(toAccount);\n        let to;\n        if (toData) {\n            to = JSON.parse(toData.toString());\n            if (to.type !== 'account') {\n                throw new Error('wrong to type');\n            }  \n        } else {\n            throw new Error('Accout to not found');\n        }\n \n        \/\/ update the balance\n        to.balance += Number(value);\n        await ctx.stub.putState(to.name, Buffer.from(JSON.stringify(to)));\n                 \n        \/\/ define and set Event\n        let Event = {\n            type: \"RefillBalance\",\n            to: to.name,\n            balanceTo: to.balance,\n            value: value\n        };\n        await ctx.stub.setEvent('RefillBalance', Buffer.from(JSON.stringify(Event)));\n \n        \/\/ return to object\n        return JSON.stringify(from);\n    }\n}\nmodule.exports = CitcoinEvents;\n<\/code><\/pre>\n<p>\nIntuitivn\u011b by tu m\u011blo b\u00fdt v\u0161echno jasn\u00e9:<\/p>\n<ul>\n<li>Existuje n\u011bkolik funkc\u00ed (AddAccount, GetAccounts, SendFrom, GetBalance, RefillBalance), kter\u00e9 bude demonstra\u010dn\u00ed program volat pomoc\u00ed Hyperledger Fabric API.<\/li>\n<li>Funkce SendFrom a RefillBalance generuj\u00ed ud\u00e1losti (Event), kter\u00e9 bude demonstra\u010dn\u00ed program p\u0159ij\u00edmat.<\/li>\n<li>Funkce instantiate \u2014 je vol\u00e1na jednou p\u0159i instanciaci smart kontraktu. Ve skute\u010dnosti nen\u00ed vol\u00e1na jednou, ale poka\u017ed\u00e9 p\u0159i zm\u011bn\u011b verze smart kontraktu. Proto inicializace seznamu pr\u00e1zdn\u00fdm polem nen\u00ed dobr\u00fd n\u00e1pad, proto\u017ee nyn\u00ed p\u0159i zm\u011bn\u011b verze smart kontraktu ztrat\u00edme aktu\u00e1ln\u00ed seznam. Ale to nevad\u00ed, j\u00e1 se jen u\u010d\u00edm).<\/li>\n<li>\u00da\u010dty (Account) a seznam \u00fa\u010dt\u016f (accounts) \u2014 jsou JSON struktury dat. Pro manipulaci s daty se pou\u017e\u00edv\u00e1 JS.<\/li>\n<li>Aktu\u00e1ln\u00ed hodnotu assetu lze z\u00edskat pomoc\u00ed vol\u00e1n\u00ed funkce getState a aktualizovat pomoc\u00ed putState.<\/li>\n<li>P\u0159i vytv\u00e1\u0159en\u00ed \u00fa\u010dtu se vol\u00e1 funkce AddAccount, ve kter\u00e9 se prov\u00e1d\u00ed porovn\u00e1n\u00ed maxim\u00e1ln\u00edho po\u010dtu \u00fa\u010dt\u016f v blockchainu (maxAccounts = 5). A zde je chyba (v\u0161imli jste si?), kter\u00e1 vede k nekone\u010dn\u00e9mu n\u00e1r\u016fstu po\u010dtu \u00fa\u010dt\u016f. Takov\u00fdch chyb je t\u0159eba se vyvarovat)<\/li>\n<\/ul>\n<p>\nD\u00e1le na\u010dteme smart kontrakt do Channel a instanciujeme jej:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: co n\u00e1s stoj\u00ed postavit PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/45ad234efc9838b711f96642988f073e.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nD\u00edv\u00e1me se na transakci pro instalaci Smart Contract:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: co n\u00e1s stoj\u00ed postavit PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/39605b9d09468fd0c5f0557ed8b692a1.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nD\u00edv\u00e1me se na podrobnosti o na\u0161em Channel:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: co n\u00e1s stoj\u00ed postavit PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/ccaf803cf34e52f77dac448f9c83e672.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nV d\u016fsledku toho z\u00edsk\u00e1v\u00e1me n\u00e1sleduj\u00edc\u00ed sch\u00e9ma blockchainov\u00e9 s\u00edt\u011b v cloudu IBM. Tak\u00e9 na sch\u00e9matu je uveden demonstra\u010dn\u00ed program b\u011b\u017e\u00edc\u00ed v cloudu Amazon na virtu\u00e1ln\u00edm serveru (dal\u0161\u00ed podrobnosti budou v n\u00e1sleduj\u00edc\u00ed \u010d\u00e1sti):<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: co n\u00e1s stoj\u00ed postavit PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/64e5c0f27d351ee3b60d2ea471a7f58c.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h2>Vytvo\u0159en\u00ed GUI pro vol\u00e1n\u00ed Hyperledger Fabric API<\/h2>\n<p>\nHyperledger Fabric m\u00e1 API, kter\u00e9 lze pou\u017e\u00edt pro:<\/p>\n<ul>\n<li>Vytvo\u0159en\u00ed channelu;<\/li>\n<li>P\u0159ipojen\u00ed peer k channelu;<\/li>\n<li>Instalaci a instanciaci smart kontrakt\u016f v channelu;<\/li>\n<li>Vol\u00e1n\u00ed transakc\u00ed;<\/li>\n<li>Dotazov\u00e1n\u00ed informac\u00ed v blockchainu.<\/li>\n<\/ul>\n<p><\/p>\n<h3>V\u00fdvoj aplikace<\/h3>\n<p>\nV na\u0161\u00ed demonstra\u010dn\u00ed aplikaci budeme pou\u017e\u00edvat API pouze pro vol\u00e1n\u00ed transakc\u00ed a dotazov\u00e1n\u00ed informac\u00ed, proto\u017ee ostatn\u00ed kroky jsme ji\u017e provedli pomoc\u00ed blockchainov\u00e9 platformy IBM. P\u00ed\u0161eme GUI, pou\u017e\u00edvaj\u00edc\u00ed standardn\u00ed technologick\u00fd stack: Express.js + Vue.js + Node.js. O tom, jak za\u010d\u00edt vytv\u00e1\u0159et modern\u00ed webov\u00e9 aplikace, by se dala napsat samostatn\u00e1 \u010dl\u00e1nek. Zde p\u0159id\u00e1m odkaz na s\u00e9rii p\u0159edn\u00e1\u0161ek, kter\u00e9 se mi nejv\u00edce l\u00edbily: <noindex><a rel=\"nofollow\" href=\"https:\/\/youtu.be\/Fa4cRMaTDUI\">Full Stack Web App using Vue.js &amp; Express.js<\/a><\/noindex>. V d\u016fsledku toho vznikla klient-server aplikace se zn\u00e1m\u00fdm grafick\u00fdm rozhran\u00edm ve stylu Material Design od Google. REST API mezi klientem a serverem se skl\u00e1d\u00e1 z n\u011bkolika vol\u00e1n\u00ed:<\/p>\n<ul>\n<li>HyperledgerDemo\/v1\/init \u2014 inicializovat blockchain;<\/li>\n<li>HyperledgerDemo\/v1\/accounts\/list \u2014 z\u00edskat seznam v\u0161ech \u00fa\u010dt\u016f;<\/li>\n<li>HyperledgerDemo\/v1\/account?name=Bob&amp;balance=100 \u2014 vytvo\u0159it \u00fa\u010det Bob;<\/li>\n<li>HyperledgerDemo\/v1\/info?account=Bob \u2014 z\u00edskat informace o \u00fa\u010dtu Bob;<\/li>\n<li>HyperledgerDemo\/v1\/transaction?from=Bob&amp;to=Alice&amp;volume=2 \u2014 p\u0159ev\u00e9st dv\u011b mince od Boba k Alici;<\/li>\n<li>HyperledgerDemo\/v1\/disconnect \u2014 ukon\u010dit p\u0159ipojen\u00ed k blockchainu.<\/li>\n<\/ul>\n<p>\nPopis API s p\u0159\u00edklady jsem um\u00edstil na<noindex><a rel=\"nofollow\" href=\"https:\/\/documenter.getpostman.com\/view\/7152141\/SVfTNSeb\"> webov\u00e9 str\u00e1nce \u201ePostman\u201c<\/a><\/noindex> \u2014 dob\u0159e zn\u00e1m\u00e9m programu pro testov\u00e1n\u00ed HTTP API.<\/p>\n<h3>Demo aplikace v cloudu Amazon<\/h3>\n<p>\nAplikaci jsem nahr\u00e1l na Amazon, proto\u017ee IBM st\u00e1le nebylo schopno upgradovat m\u016fj \u00fa\u010det a povolit mi vytv\u00e1\u0159et virtu\u00e1ln\u00ed servery. Jako t\u0159e\u0161ni\u010dku jsem p\u0159id\u011blal dom\u00e9nu: <noindex><a rel=\"nofollow\" href=\"http:\/\/www.citcoin.info\">www.citcoin.info<\/a><\/noindex>. Trochu podr\u017e\u00edm server zapnut\u00fd, pak ho vypnu, proto\u017ee centy za pron\u00e1jem naskakuj\u00ed, a mince citcoin na burze je\u0161t\u011b nejsou kotov\u00e1ny) Do \u010dl\u00e1nku p\u0159ikl\u00e1d\u00e1m screenshoty dema, aby byla jasn\u00e1 logika pr\u00e1ce. Demo aplikace m\u016f\u017ee:<\/p>\n<ul>\n<li>Inicializovat blockchain;<\/li>\n<li>Vytv\u00e1\u0159et \u00fa\u010det (ale nyn\u00ed nov\u00fd \u00fa\u010det nelze vytvo\u0159it, proto\u017ee v blockchainu bylo dosa\u017eeno maxim\u00e1ln\u00edho po\u010dtu \u00fa\u010dt\u016f, jak je uvedeno ve smart kontraktu);<\/li>\n<li>Z\u00edskat seznam \u00fa\u010dt\u016f;<\/li>\n<li>P\u0159ev\u00e1d\u011bt mince citcoin mezi Alic\u00ed, Bobem a Alexem;<\/li>\n<li>Z\u00edsk\u00e1vat ud\u00e1losti (ale moment\u00e1ln\u011b nen\u00ed mo\u017en\u00e9 ud\u00e1losti zobrazit, tak\u017ee v rozhran\u00ed pro jednoduchost je uvedeno, \u017ee ud\u00e1losti nejsou podporov\u00e1ny);<\/li>\n<li>Logovat akce.<\/li>\n<\/ul>\n<p>\nNejprve inicializujeme blockchain:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: co n\u00e1s stoj\u00ed postavit PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/773ce08270f1b22e64a79fce267bb25f.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nD\u00e1le zakl\u00e1d\u00e1me sv\u016fj \u00fa\u010det, ne\u0161et\u0159\u00edme s bilanc\u00ed:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: co n\u00e1s stoj\u00ed postavit PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/f1cd24aedd5e9618046c5e1ab49ceede.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nZ\u00edsk\u00e1v\u00e1me seznam v\u0161ech dostupn\u00fdch \u00fa\u010dt\u016f:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: co n\u00e1s stoj\u00ed postavit PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/796f897ca1345430f755055372d03421.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nVybereme odes\u00edlatele a p\u0159\u00edjemce, z\u00edsk\u00e1me jejich z\u016fstatky. Pokud je odes\u00edlatel a p\u0159\u00edjemce stejn\u00fd, dojde k dopln\u011bn\u00ed jeho \u00fa\u010dtu:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: co n\u00e1s stoj\u00ed postavit PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/58eb2ed4a4bac51e0dca1b0331d7910a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nV logu sledujeme prov\u00e1d\u011bn\u00ed transakc\u00ed:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: co n\u00e1s stoj\u00ed postavit PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/528760998e8dc27a73c4409f55b22087.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nS demoprogramem je to v\u0161e. D\u00e1le si m\u016f\u017eeme prohl\u00e9dnout na\u0161i transakci v blockchainu:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: co n\u00e1s stoj\u00ed postavit PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/1d6bc12f3609b118472afec31b089f09.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nA celkov\u00fd seznam transakc\u00ed:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: co n\u00e1s stoj\u00ed postavit PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/96675fcda8088307326dadf7852e6ce7.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nT\u00edmto jsme \u00fasp\u011b\u0161n\u011b dokon\u010dili implementaci PoC pro vytvo\u0159en\u00ed s\u00edt\u011b Citcoin. Co je\u0161t\u011b mus\u00edme ud\u011blat, aby se Citcoin stal plnohodnotnou s\u00edt\u00ed pro p\u0159evod minc\u00ed? Je toho jen m\u00e1lo:<\/p>\n<ul>\n<li>V etap\u011b vytv\u00e1\u0159en\u00ed \u00fa\u010dtu realizovat generaci soukrom\u00e9ho\/publikovan\u00e9ho kl\u00ed\u010de. Soukrom\u00fd kl\u00ed\u010d by m\u011bl b\u00fdt uchov\u00e1v\u00e1n u u\u017eivatele \u00fa\u010dtu, ve\u0159ejn\u00fd v blockchainu.<\/li>\n<li>Prov\u00e9st p\u0159evod minc\u00ed, ve kter\u00e9m k identifikaci u\u017eivatele se pou\u017e\u00edv\u00e1 nikoli jm\u00e9no, ale ve\u0159ejn\u00fd kl\u00ed\u010d.<\/li>\n<li>\u0160ifrovat transakce, kter\u00e9 jdou od u\u017eivatele na server jeho soukrom\u00fdm kl\u00ed\u010dem.<\/li>\n<\/ul>\n<p><\/p>\n<h2>Z\u00e1v\u011br <\/h2>\n<p>\nRealizovali jsme s\u00ed\u0165 Citcoin s funkcemi: p\u0159idat \u00fa\u010det, z\u00edskat z\u016fstatek, dob\u00edt sv\u016fj \u00fa\u010det, p\u0159ev\u00e9st mince z jednoho \u00fa\u010dtu na druh\u00fd. Tak co n\u00e1s st\u00e1lo postavit PoC?<\/p>\n<ul>\n<li>Je t\u0159eba studovat blockchain obecn\u011b a Hyperledger Fabric konkr\u00e9tn\u011b;<\/li>\n<li>Nau\u010dit se pou\u017e\u00edvat cloudov\u00e9 slu\u017eby IBM nebo Amazon;<\/li>\n<li>Nau\u010dit se programovac\u00ed jazyk JS a n\u011bjak\u00fd webov\u00fd framework;<\/li>\n<li>Pokud je pot\u0159eba uchov\u00e1vat n\u011bjak\u00e1 data nikoli v blockchainu, ale v samostatn\u00e9 datab\u00e1zi, nau\u010dit se integrovat nap\u0159\u00edklad s PostgreSQL;<\/li>\n<li>A posledn\u00ed na seznamu, ale ne m\u00e9n\u011b d\u016fle\u017eit\u00e9 \u2014 bez znalosti Linuxu se v modern\u00edm sv\u011bt\u011b nikam nedostanete!)<\/li>\n<\/ul>\n<p>\nOczywi\u015bcie to nen\u00ed rocket science, ale potr\u00e1pit se budete muset!<\/p>\n<h3>Zdrojov\u00e9 k\u00f3dy na GitHubu<\/h3>\n<p>\nZdrojov\u00e9 k\u00f3dy jsem polo\u017eil na <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/AlexeySushkov\/Citcoin-blockchain\">GitHub<\/a><\/noindex>. Kr\u00e1tk\u00fd popis repozit\u00e1\u0159e:<br \/>\nKatalog &#171;<b>server<\/b>&#187; \u2014 Node.js server<br \/>\nKatalog &#171;<b>client<\/b>&#187; \u2014 Node.js klient<br \/>\nKatalog &#171;<b>blockchain<\/b>&#187; (hodnoty parametr\u016f a kl\u00ed\u010de, samoz\u0159ejm\u011b, nefunk\u010dn\u00ed a uveden\u00e9 pouze jako p\u0159\u00edklad):<\/p>\n<ul>\n<li>contract \u2014 zdrojov\u00fd k\u00f3d chytr\u00e9ho kontraktu<\/li>\n<li>wallet \u2014 kl\u00ed\u010de u\u017eivatele pro pou\u017eit\u00ed Hyperledger Fabric API. <\/li>\n<li>*.cds \u2014 zkompilovan\u00e9 verze chytr\u00fdch kontrakt\u016f<\/li>\n<li>*.json soubory \u2014 p\u0159\u00edklady konfigura\u010dn\u00edch soubor\u016f pro pou\u017eit\u00ed Hyperledger Fabric API<\/li>\n<\/ul>\n<p>\n<b>Je to teprve za\u010d\u00e1tek!<\/b><br \/>\n<br \/>Zdroj: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/466157\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0413\u043b\u0430\u0437\u0430 \u0431\u043e\u044f\u0442\u0441\u044f, \u0430 \u0440\u0443\u043a\u0438 \u0447\u0435\u0448\u0443\u0442\u0441\u044f! \u0412 \u043f\u0440\u043e\u0448\u043b\u044b\u0445 \u0441\u0442\u0430\u0442\u044c\u044f\u0445 \u043c\u044b \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043b\u0438\u0441\u044c \u0441 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u044f\u043c\u0438, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0441\u0442\u0440\u043e\u044f\u0442\u0441\u044f \u0431\u043b\u043e\u043a\u0447\u0435\u0439\u043d\u044b (\u0427\u0442\u043e \u043d\u0430\u043c \u0441\u0442\u043e\u0438\u0442 \u0431\u043b\u043e\u043a\u0447\u0435\u0439\u043d \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c?) \u0438 \u043a\u0435\u0439\u0441\u0430\u043c\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0436\u043d\u043e \u0441 \u0438\u0445 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c (\u0427\u0442\u043e \u043d\u0430\u043c \u0441\u0442\u043e\u0438\u0442 \u043a\u0435\u0439\u0441 \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c?). \u041d\u0430\u0441\u0442\u0430\u043b\u043e \u0432\u0440\u0435\u043c\u044f \u043f\u043e\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0440\u0443\u043a\u0430\u043c\u0438! \u0414\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u0438\u043b\u043e\u0442\u043e\u0432 \u0438 PoC (Proof of Concept) \u044f \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0438\u0442\u0430\u044e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0431\u043b\u0430\u043a\u0430, \u0442.\u043a. \u043a \u043d\u0438\u043c \u0435\u0441\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":28421,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-37868","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.3 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0413\u043b\u0430\u0437\u0430 \u0431\u043e\u044f\u0442\u0441\u044f, \u0430 \u0440\u0443\u043a\u0438 \u0447\u0435\u0448\u0443\u0442\u0441\u044f! \u0412 \u043f\u0440\u043e\u0448\u043b\u044b\u0445 \u0441\u0442\u0430\u0442\u044c\u044f\u0445 \u043c\u044b \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043b\u0438\u0441\u044c \u0441 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u044f\u043c\u0438, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0441\u0442\u0440\u043e\u044f\u0442\u0441\u044f \u0431\u043b\u043e\u043a\u0447\u0435\u0439\u043d\u044b (\u0427\u0442\u043e \u043d\u0430\u043c \u0441\u0442\u043e\u0438\u0442 \u0431\u043b\u043e\u043a\u0447\u0435\u0439\u043d.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/cs\/blog\/administrirovanie\/blokchejn-chto-nam-stoit-poc-postroit\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"cs_CZ\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u0411\u043b\u043e\u043a\u0447\u0435\u0439\u043d: \u0447\u0442\u043e \u043d\u0430\u043c \u0441\u0442\u043e\u0438\u0442 PoC \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c? | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0413\u043b\u0430\u0437\u0430 \u0431\u043e\u044f\u0442\u0441\u044f, \u0430 \u0440\u0443\u043a\u0438 \u0447\u0435\u0448\u0443\u0442\u0441\u044f! \u0412 \u043f\u0440\u043e\u0448\u043b\u044b\u0445 \u0441\u0442\u0430\u0442\u044c\u044f\u0445 \u043c\u044b \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043b\u0438\u0441\u044c \u0441 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u044f\u043c\u0438, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0441\u0442\u0440\u043e\u044f\u0442\u0441\u044f \u0431\u043b\u043e\u043a\u0447\u0435\u0439\u043d\u044b (\u0427\u0442\u043e \u043d\u0430\u043c \u0441\u0442\u043e\u0438\u0442 \u0431\u043b\u043e\u043a\u0447\u0435\u0439\u043d.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/cs\/blog\/administrirovanie\/blokchejn-chto-nam-stoit-poc-postroit\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T19:20:16+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T19:20:16+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Blockchain: co n\u00e1s stoj\u00ed postavit PoC? | ProHoster","description":"O\u010di se boj\u00ed, ale ruce se drbou! V p\u0159edchoz\u00edch \u010dl\u00e1nc\u00edch jsme se zab\u00fdvali technologiemi, na kter\u00fdch jsou blockchainy postaveny (Co n\u00e1s stoj\u00ed blockchain.","canonical_url":"https:\/\/prohoster.info\/cs\/blog\/administrirovanie\/blokchejn-chto-nam-stoit-poc-postroit","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"cs_CZ","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u0411\u043b\u043e\u043a\u0447\u0435\u0439\u043d: \u0447\u0442\u043e \u043d\u0430\u043c \u0441\u0442\u043e\u0438\u0442 PoC \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c? | ProHoster","og:description":"\u0413\u043b\u0430\u0437\u0430 \u0431\u043e\u044f\u0442\u0441\u044f, \u0430 \u0440\u0443\u043a\u0438 \u0447\u0435\u0448\u0443\u0442\u0441\u044f! \u0412 \u043f\u0440\u043e\u0448\u043b\u044b\u0445 \u0441\u0442\u0430\u0442\u044c\u044f\u0445 \u043c\u044b \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043b\u0438\u0441\u044c \u0441 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u044f\u043c\u0438, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0441\u0442\u0440\u043e\u044f\u0442\u0441\u044f \u0431\u043b\u043e\u043a\u0447\u0435\u0439\u043d\u044b (\u0427\u0442\u043e \u043d\u0430\u043c \u0441\u0442\u043e\u0438\u0442 \u0431\u043b\u043e\u043a\u0447\u0435\u0439\u043d.","og:url":"https:\/\/prohoster.info\/cs\/blog\/administrirovanie\/blokchejn-chto-nam-stoit-poc-postroit","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T19:20:16+00:00","article:modified_time":"2019-10-31T19:20:16+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"37868","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-23 19:34:11","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 01:19:22","updated":"2026-01-23 19:34:11","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/posts\/37868","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/comments?post=37868"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/posts\/37868\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/media\/28421"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/media?parent=37868"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/categories?post=37868"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/tags?post=37868"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}