{"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\/ro\/blog\/administrirovanie\/blokchejn-chto-nam-stoit-poc-postroit","title":{"rendered":"Blockchain: ce ne cost\u0103 s\u0103 construim un PoC?","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><i>Ochi se tem, dar m\u00e2inile m\u0103 g\u00e2ndesc s\u0103 lucreze!<\/i><\/p>\n<p>\u00cen articolele anterioare, am discutat despre tehnologiile pe care se bazeaz\u0103 blockhain-urile (<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/443282\/\">Ce ne-ar costa s\u0103 construim un blockchain?<\/a><\/noindex>) \u0219i cazurile care pot fi realizate cu ajutorul lor (<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/449986\/\">Ce ne-ar costa s\u0103 construim un caz?<\/a><\/noindex>). A venit momentul s\u0103 trecem la treab\u0103! Pentru realizarea pilotilor \u0219i PoC (Proof of Concept), prefer s\u0103 folosesc cloud-uri, deoarece acestea sunt accesibile din orice col\u021b al lumii \u0219i, adesea, nu este necesar s\u0103 pierd timp cu instalarea plictisitoare a mediului, deoarece exist\u0103 configura\u021bii preinstalate. A\u0219adar, s\u0103 facem ceva simplu, de exemplu, o re\u021bea pentru transferul de monede \u00eentre participan\u021bi \u0219i s\u0103 o numim modest Ccoin. Pentru aceasta, vom folosi cloud-ul IBM \u0219i blockchain-ul versatil Hyperledger Fabric. La \u00eenceput, s\u0103 \u00een\u021belegem de ce Hyperledger Fabric este numit blockchain versatil?<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: ce ne cost\u0103 s\u0103 construim un 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 blockchain versatil<\/h2>\n<p>\nDac\u0103 vorbim \u00een general, un sistem informa\u021bional versatil este:<\/p>\n<ul>\n<li>Un set de servere \u0219i un nucleu software care execut\u0103 logica de afaceri;<\/li>\n<li>Interfe\u021be pentru interac\u021biunea cu sistemul;<\/li>\n<li>Instrumente pentru \u00eenregistrarea, autentificarea \u0219i autorizarea dispozitivelor\/oamenilor;<\/li>\n<li>O baz\u0103 de date care stocheaz\u0103 date opera\u021bionale \u0219i arhivate:<\/li>\n<\/ul>\n<p>\n<img decoding=\"async\" alt=\"Blockchain: ce ne cost\u0103 s\u0103 construim un PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/f11fe73de54b0573d44fae903d367df9.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDespre ce este Hyperledger Fabric se poate citi \u00een versiunea oficial\u0103 pe <noindex><a rel=\"nofollow\" href=\"https:\/\/www.hyperledger.org\">site<\/a><\/noindex>, dar pe scurt, Hyperledger Fabric este o platform\u0103 opensource, care permite construirea de blockchain-uri private \u0219i executarea de contracte inteligente scrise \u00een limbaje de programare JS \u0219i Go. S\u0103 arunc\u0103m o privire detaliat\u0103 asupra arhitecturii Hyperledger Fabric \u0219i s\u0103 ne asigur\u0103m c\u0103 este un sistem versatil, \u00een care doar exist\u0103 specificit\u0103\u021bi legate de stocarea \u0219i \u00eenregistrarea datelor. Specificitatea const\u0103 \u00een faptul c\u0103 datele, la fel ca \u00een toate blockchain-urile, sunt stocate \u00een blocuri, care sunt introduse \u00een blockchain doar dac\u0103 participan\u021bii au ajuns la un consens, iar dup\u0103 \u00eenregistrare, datele nu pot fi modificate sau \u0219terse f\u0103r\u0103 s\u0103 se observe.<\/p>\n<h2>Arhitectura Hyperledger Fabric<\/h2>\n<p>\n\u00cen diagram\u0103 este prezentat\u0103 arhitectura Hyperledger Fabric:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: ce ne cost\u0103 s\u0103 construim un PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/7488d70b330af2bbae1db67005f22a3e.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<b>Organiza\u021bii <\/b> \u2014 organiza\u021biile con\u021bin peer-uri, astfel \u00eenc\u00e2t blockchain-ul exist\u0103 datorit\u0103 sprijinului organiza\u021biilor. Diferite organiza\u021bii pot face parte din acela\u0219i canal.<\/p>\n<p><b>Canal <\/b> \u2014 o structur\u0103 logic\u0103 care grupeaz\u0103 peer-urile, astfel fiind stabilit blockchain-ul. Hyperledger Fabric poate procesa simultan mai multe blockchain-uri cu logici de afaceri diferite.<\/p>\n<p><b>Provider de Servicii de Membru (MSP)<\/b> \u2014 este CA (Autoritate de Certificare) pentru emiterea identit\u0103\u021bii \u0219i desemnarea rolurilor. Pentru a crea un nod, trebuie s\u0103 interactuezi cu MSP.<\/p>\n<p><b>Noduri peer<\/b> \u2014 verific\u0103 tranzac\u021biile, stocheaz\u0103 blockchain-ul, execut\u0103 contracte inteligente \u0219i interac\u021bioneaz\u0103 cu aplica\u021biile. Nodurile peer au o identitate (certificat digital), emis\u0103 de MSP. Spre deosebire de re\u021belele Bitcoin sau Ethereum, unde toate nodurile sunt egale, \u00een Hyperledger Fabric nodurile joac\u0103 roluri diferite:<\/p>\n<ul>\n<li>Un nod peer poate fi <b>nodat\u0103 endorsing peer<\/b> (EP) \u0219i poate executa contracte inteligente.<\/li>\n<li><b>Committing peer<\/b> (CP) \u2014 doar stocheaz\u0103 date \u00een blockchain \u0219i actualizeaz\u0103 \u201eWorld state\u201d.<\/li>\n<li><b>Anchor Peer<\/b> (AP) \u2014 dac\u0103 \u00een blockchain particip\u0103 mai multe organiza\u021bii, nodurile anchor sunt folosite pentru a face leg\u0103tura \u00eentre ele. Fiecare organiza\u021bie trebuie s\u0103 aib\u0103 unul sau mai multe noduri anchor. Prin intermediul AP, orice nod dintr-o organiza\u021bie poate ob\u021bine informa\u021bii despre toate nodurile din alte organiza\u021bii. Pentru sincronizarea informa\u021biilor \u00eentre AP se folose\u0219te <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Gossip_protocol\">protocolul gossip<\/a><\/noindex>.<\/li>\n<li><b>Leader Peer<\/b> \u2014 dac\u0103 o organiza\u021bie are mai multe noduri, doar nodul lider va primi blocuri din serviciul de ordonare \u0219i le va distribui celorlalte noduri. Liderul poate fi stabilit static sau ales dinamic de nodurile din organiza\u021bie. Pentru sincronizarea informa\u021biilor despre lideri, de asemenea, se utilizeaz\u0103 protocolul gossip.<\/li>\n<\/ul>\n<p>\n<b>Active <\/b> \u2014 entit\u0103\u021bi care au valoare \u0219i care sunt stocate \u00een blockchain. Mai precis \u2014 sunt date de tip key-value \u00een format JSON. Aceste date sunt cele care sunt \u00eenregistrate \u00een blockchain \u201eBlockchain\u201d. Ele au o istorie stocat\u0103 \u00een blockchain \u0219i o stare curent\u0103, care este stocat\u0103 \u00een baza de date \u201eWorld state\u201d. Structurile de date sunt umplute aleatoriu \u00een func\u021bie de obiectivele de afaceri. Nu exist\u0103 c\u00e2mpuri obligatorii, singura recomandare este ca activele s\u0103 aib\u0103 un proprietar \u0219i s\u0103 reprezinte o valoare. <\/p>\n<p><b>Registru <\/b> \u2014 const\u0103 \u00een blockchain \u201eBlockchain\u201d \u0219i baza de date \u201eWorld state\u201d, \u00een care este stocat\u0103 starea actual\u0103 a activelor. World state folose\u0219te LevelDB sau CouchDB.<\/p>\n<p><b>Contract inteligent<\/b> \u2014 prin intermediul contractelor inteligente se implementeaz\u0103 logica de afaceri a sistemului. \u00cen Hyperledger Fabric, contractele inteligente se numesc chaincode. Prin chaincode se definesc activele \u0219i tranzac\u021biile pe care le implic\u0103. Vorbind tehnic, contractele inteligente sunt module software implementate \u00een limbaje de programare JS sau Go.<\/p>\n<p><b>Politica de aprobat<\/b> \u2014 pentru fiecare chaincode se poate defini politici privind c\u00e2te \u0219i de la cine sunt necesare aprob\u0103rile pentru o tranzac\u021bie. Dac\u0103 politica nu este definit\u0103, \u00een mod implicit se folose\u0219te: \u201etranzac\u021bia trebuie s\u0103 fie aprobat\u0103 de orice membru al oric\u0103rei organiza\u021bii din canal\u201d. Exemple de politici:<\/p>\n<ul>\n<li>Transac\u021bia trebuie s\u0103 fie confirmat\u0103 de c\u0103tre orice administrator al organiza\u021biei;<\/li>\n<li>Trebuie s\u0103 fie confirmat\u0103 de orice membru sau client al organiza\u021biei;<\/li>\n<li>Trebuie s\u0103 fie confirmat\u0103 de orice peer al organiza\u021biei.<\/li>\n<\/ul>\n<p>\n<b>Serviciul de Ordering<\/b> \u2014 \u00eempacheteaz\u0103 tranzac\u021biile \u00een blocuri \u0219i le trimite peer-urilor \u00een canal. Asigur\u0103 livrarea mesajelor tuturor peer-urilor din re\u021bea. Pentru sistemele industriale se folose\u0219te <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/Apache_Kafka\">brokerul de mesaje Kafka<\/a><\/noindex>, pentru dezvoltare \u0219i testare <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: ce ne cost\u0103 s\u0103 construim un PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/9060864bd1002da881d7f17ef8ec0b0c.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<ul>\n<li>Aplica\u021bia interac\u021bioneaz\u0103 cu Hyperledger Fabric, utiliz\u00e2nd SDK-uri Go, Node.js sau Java;<\/li>\n<li>Clientul creeaz\u0103 tranzac\u021bia tx \u0219i o trimite c\u0103tre peer-urile de endorsare;<\/li>\n<li>Peer-ul verific\u0103 semn\u0103tura clientului, execut\u0103 tranzac\u021bia \u0219i trimite semn\u0103tura de endorsare \u00eenapoi clientului. Chaincode-urile se execut\u0103 doar pe peer-urile de endorsare, iar rezultatul execu\u021biei este distribuit tuturor peer-urilor. Acest algoritm de func\u021bionare se nume\u0219te \u2014 consens PBFT (Practical Byzantine Fault Tolerant). Se deosebe\u0219te de <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Byzantine_fault\">classica BFT<\/a><\/noindex> prin faptul c\u0103 mesajul este trimis \u0219i se a\u0219teapt\u0103 confirmarea nu de la to\u021bi participan\u021bii, ci doar de la un set specific;<\/li>\n<li>Dup\u0103 ce clientul prime\u0219te num\u0103rul de r\u0103spunsuri corespunz\u0103tor politicii de endorsare, trimite tranzac\u021bia la serviciul de Ordering;<\/li>\n<li>Serviciul de Ordering formeaz\u0103 blocul \u0219i \u00eel trimite tuturor peer-urilor de committing. Serviciul de Ordering asigur\u0103 \u00eenregistrarea secven\u021bial\u0103 a blocurilor, ceea ce exclude, a\u0219a-zisul, ledger fork (<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/443282\/\">vezi sec\u021biunea \u201eForks\u201d<\/a><\/noindex>);<\/li>\n<li>Peer-urile primesc blocul, verific\u0103 din nou politica de endorsare, \u00eenregistreaz\u0103 blocul \u00een blockchain \u0219i schimb\u0103 starea \u00een baza de date \u201eWorld state\u201d.<\/li>\n<\/ul>\n<p>\nAdic\u0103, se ob\u021bine o separare a rolurilor \u00eentre noduri. Aceasta asigur\u0103 scalabilitatea \u0219i securitatea blockchain-ului:<\/p>\n<ul>\n<li>Smart contractele (chaincode) sunt executate de peer-urile de endorsare. Aceasta asigur\u0103 confiden\u021bialitatea smart contractelor, deoarece ele nu sunt stocate de to\u021bi participan\u021bii, ci doar pe peer-urile de endorsare.<\/li>\n<li>Ordering trebuie s\u0103 func\u021bioneze rapid. Acest lucru este asigurat prin faptul c\u0103 Ordering formeaz\u0103 doar blocul \u0219i \u00eel trimite unui set fix de peer-uri lider.<\/li>\n<li>Committing peers doar stocheaz\u0103 blockchainul \u2014 pot fi multe \u0219i nu necesit\u0103 putere mare de procesare \u0219i lucru instantaneu. <\/li>\n<\/ul>\n<p>\nMai multe detalii despre solu\u021biile arhitecturale Hyperledger Fabric \u0219i de ce func\u021bioneaz\u0103 a\u0219a, nu altfel, pot fi consultate aici: <noindex><a rel=\"nofollow\" href=\"https:\/\/hyperledger-fabric.readthedocs.io\/en\/latest\/arch-deep-dive.html\">Origins Architecture<\/a><\/noindex> sau aici: <noindex><a rel=\"nofollow\" href=\"https:\/\/arxiv.org\/abs\/1801.10228v2\">Hyperledger Fabric: A Distributed Operating System for Permissioned Blockchains<\/a><\/noindex>.<\/p>\n<p>A\u0219adar, Hyperledger Fabric este cu adev\u0103rat un sistem versatil, cu ajutorul c\u0103ruia se poate:<\/p>\n<ul>\n<li>Implementa orice logic\u0103 de afaceri, utiliz\u00e2nd mecanismul smart contractelor;<\/li>\n<li>Scrie\u021bi \u0219i ob\u021bine\u021bi date dintr-o baz\u0103 de date blockchain \u00een format JSON;<\/li>\n<li>Furniza\u021bi \u0219i verifica\u021bi accesul la API, folosind Autoritatea de Certificare. <\/li>\n<\/ul>\n<p>\nAcum, c\u0103 am \u00een\u021beles un pic despre specificul Hyperledger Fabric, s\u0103 facem \u00een sf\u00e2r\u0219it ceva util!<\/p>\n<h2>Desf\u0103\u0219ur\u0103m blockchain-ul<\/h2>\n<p><\/p>\n<h3>Formularea problemei<\/h3>\n<p>\nSarcina este s\u0103 implement\u0103m o re\u021bea Citcoin cu urm\u0103toarele func\u021bii: crearea unui cont, ob\u021binerea soldului, alimentarea contului, transferul de monede de la un cont la altul. Vom schi\u021ba un model obiect care va fi implementat ulterior \u00een contractul inteligent. A\u0219adar, vom avea conturi care se identific\u0103 prin nume (name) \u0219i con\u021bin un sold (balance), \u0219i o list\u0103 de conturi. Conturile \u0219i lista de conturi sunt, \u00een termeni de Hyperledger Fabric, active (assets). Prin urmare, acestea au o istorie \u0219i un stadiu curent. Voi \u00eencerca s\u0103 ilustrez acest lucru:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: ce ne cost\u0103 s\u0103 construim un PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/a4f111da59bc7982b51d583857db6d5a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nFigurile de sus reprezint\u0103 stadiul curent, care este stocat \u00een baza de date \u201eWorld state\u201d. Sub ele sunt figurile care ilustreaz\u0103 istoria, care este stocat\u0103 \u00een blockchain. Stadiul curent al activelor se schimb\u0103 prin tranzac\u021bii. Activele se schimb\u0103 doar \u00een \u00eentregime, astfel \u00eenc\u00e2t, \u00een urma execut\u0103rii tranzac\u021biei, se creeaz\u0103 un nou obiect, iar valoarea curent\u0103 a activului va merge \u00een istorie. <\/p>\n<h3>Cloud IBM <\/h3>\n<p>\nCre\u0103m un cont \u00een <noindex><a rel=\"nofollow\" href=\"https:\/\/cloud.ibm.com\">cloudul IBM<\/a><\/noindex>. Pentru a utiliza platforma blockchain, aceasta trebuie s\u0103 fie actualizat\u0103 la Pay-As-You-Go. Acest proces poate s\u0103 nu fie rapid, deoarece IBM cere informa\u021bii suplimentare \u0219i le verific\u0103 manual. Pe partea pozitiv\u0103, pot spune c\u0103 IBM are materialele de \u00eenv\u0103\u021bare destul de bune, care permit desf\u0103\u0219urarea Hyperledger Fabric \u00een cloud-ul lor. Mi-a pl\u0103cut urm\u0103torul ciclu de articole \u0219i exemple:<\/p>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/IBM\/Create-BlockchainNetwork-IBPV20\/blob\/master\/README.md\">Creeaz\u0103 o re\u021bea blockchain de baz\u0103 folosind Blockchain Platform<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/IBM\/SmartContractTrading-wFabric1-4-VSCodeExt\/blob\/master\/README.md\">Creeaz\u0103 \u0219i execut\u0103 un contract inteligent blockchain<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/IBM\/auction-events\/blob\/master\/README.md\">Emite evenimente din Blockchain Platform<\/a><\/noindex><\/li>\n<\/ul>\n<p>\nMai jos sunt capturi de ecran ale platformei Blockchain IBM. Acesta nu este un ghid pentru crearea blockchain-ului, ci doar o demonstra\u021bie a amploarei sarcinii. A\u0219adar, pentru scopurile noastre, vom crea o Organiza\u021bie:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: ce ne cost\u0103 s\u0103 construim un PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/7cb30cade6315abc69f4322a2dbcd094.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n\u00cen aceasta vom crea noduri: Orderer CA, Org1 CA, Orderer Peer:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: ce ne cost\u0103 s\u0103 construim un PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/4a2239a9b7ded8ba5a11ffad86a35094.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nCre\u0103m utilizatori:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: ce ne cost\u0103 s\u0103 construim un PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/6792b12c9316f47b0cdfaf771dacc782.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nCreeaz\u0103 un Canal \u0219i nume\u0219te-l citcoin:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: ce ne cost\u0103 s\u0103 construim un PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/ea3983f209326713dcd25762c348ac96.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nPractic, Canalul este blockchain-ul, a\u0219a c\u0103 \u00eencepe cu blocul zero (Genesis block):<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: ce ne cost\u0103 s\u0103 construim un PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/416df6b6ef832c6550a2642592e57250.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h3>Scriem Smart Contract<\/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>\nIntuitiv, ar trebui s\u0103 fie totul clar aici:<\/p>\n<ul>\n<li>Exist\u0103 c\u00e2teva func\u021bii (AddAccount, GetAccounts, SendFrom, GetBalance, RefillBalance) care vor fi apelate de programul demo prin intermediul API-ului Hyperledger Fabric.<\/li>\n<li>Func\u021biile SendFrom \u0219i RefillBalance genereaz\u0103 evenimente (Event) pe care programul demo le va primi.<\/li>\n<li>Func\u021bia instantiate este apelat\u0103 o singur\u0103 dat\u0103 la instan\u021bierea unui contract inteligent. De fapt, ea este apelat\u0103 nu o singur\u0103 dat\u0103, ci de fiecare dat\u0103 c\u00e2nd versiunea contractului inteligent se schimb\u0103. Prin urmare, ini\u021bializarea listei cu un array gol este o idee proast\u0103, deoarece acum, c\u00e2nd schimb\u0103m versiunea contractului inteligent, vom pierde lista curent\u0103. Dar nimic, eu doar \u00eenv\u0103\u021b).<\/li>\n<li>Account-urile \u0219i lista account-urilor (accounts) sunt structuri de date JSON. Pentru manipularea datelor se folose\u0219te JS.<\/li>\n<li>Pentru a ob\u021bine valoarea curent\u0103 a asset-ului, se poate utiliza apelul func\u021biei getState, iar pentru a actualiza se folose\u0219te putState.<\/li>\n<li>La crearea unui Account se apeleaz\u0103 func\u021bia AddAccount, \u00een care se compar\u0103 num\u0103rul maxim de account-uri \u00een blockchain (maxAccounts = 5). \u0218i aici este o eroare (a\u021bi observat?), care duce la o cre\u0219tere infinit\u0103 a num\u0103rului de account-uri. Astfel de erori trebuie evitate)<\/li>\n<\/ul>\n<p>\nApoi, \u00eenc\u0103rc\u0103m contractul inteligent \u00een Channel \u0219i \u00eel instan\u021biem:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: ce ne cost\u0103 s\u0103 construim un PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/45ad234efc9838b711f96642988f073e.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nPrivim tranzac\u021bia de instalare a Smart Contract-ului:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: ce ne cost\u0103 s\u0103 construim un PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/39605b9d09468fd0c5f0557ed8b692a1.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nPrivim detalii despre Channel-ul nostru:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: ce ne cost\u0103 s\u0103 construim un PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/ccaf803cf34e52f77dac448f9c83e672.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nCa rezultat, ob\u021binem urm\u0103toarea schem\u0103 a re\u021belei blockchain \u00een cloud-ul IBM. De asemenea, \u00een schem\u0103 se afl\u0103 un program demo, care ruleaz\u0103 \u00een cloud-ul Amazon pe un server virtual (detalii despre el vor fi \u00een urm\u0103toarea sec\u021biune):<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: ce ne cost\u0103 s\u0103 construim un PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/64e5c0f27d351ee3b60d2ea471a7f58c.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h2>Crearea GUI pentru apelarea API-ului Hyperledger Fabric<\/h2>\n<p>\nHyperledger Fabric dispune de un API, care poate fi utilizat pentru:<\/p>\n<ul>\n<li>Crearea de channel;<\/li>\n<li>Conectarea peer-ului la channel;<\/li>\n<li>Instalarea \u0219i instan\u021bierea contractelor inteligente \u00een channel;<\/li>\n<li>Apelarea tranzac\u021biilor;<\/li>\n<li>Solicitarea de informa\u021bii \u00een blockchain.<\/li>\n<\/ul>\n<p><\/p>\n<h3>Dezvoltarea aplica\u021biei<\/h3>\n<p>\n\u00cen programul nostru demo, vom folosi API-ul doar pentru apelarea tranzac\u021biilor \u0219i solicitarea de informa\u021bii, deoarece celelalte etape au fost deja realizate, utiliz\u00e2nd platforma blockchain IBM. Scriem GUI, folosind stiva standard de tehnologii: Express.js + Vue.js + Node.js. Despre cum s\u0103 \u00eencepi s\u0103 creezi aplica\u021bii web moderne se poate scrie un articol separat. Aici voi l\u0103sa un link c\u0103tre seria de cursuri, care mi-a pl\u0103cut cel mai mult: <noindex><a rel=\"nofollow\" href=\"https:\/\/youtu.be\/Fa4cRMaTDUI\">Full Stack Web App using Vue.js &amp; Express.js<\/a><\/noindex>. Ca rezultat, a rezultat o aplica\u021bie client-server cu o interfa\u021b\u0103 grafic\u0103 familiar\u0103 \u00een stil Material Design de la Google. REST API-ul \u00eentre client \u0219i server const\u0103 din mai multe apeluri:<\/p>\n<ul>\n<li>HyperledgerDemo\/v1\/init \u2014 ini\u021bializeaz\u0103 blockchain-ul;<\/li>\n<li>HyperledgerDemo\/v1\/accounts\/list \u2014 ob\u021bine lista tuturor account-urilor;<\/li>\n<li>HyperledgerDemo\/v1\/account?name=Bob&amp;balance=100 \u2014 creeaz\u0103 account-ul Bob;<\/li>\n<li>HyperledgerDemo\/v1\/info?account=Bob \u2014 ob\u021bine informa\u021bii despre account-ul Bob;<\/li>\n<li>HyperledgerDemo\/v1\/transaction?from=Bob&amp;to=Alice&amp;volume=2 \u2014 transfer dou\u0103 monede de la Bob la Alice;<\/li>\n<li>HyperledgerDemo\/v1\/disconnect \u2014 \u00eenchide conexiunea cu blockchain-ul.<\/li>\n<\/ul>\n<p>\nAm pus descrierea API-ului cu exemple pe<noindex><a rel=\"nofollow\" href=\"https:\/\/documenter.getpostman.com\/view\/7152141\/SVfTNSeb\"> site-ul \u201ePostman\u201d<\/a><\/noindex> \u2014 un program bine cunoscut pentru testarea API-urilor HTTP.<\/p>\n<h3>Aplica\u021bia demo \u00een cloud-ul Amazon<\/h3>\n<p>\nAm \u00eenc\u0103rcat aplica\u021bia pe Amazon, deoarece IBM \u00eenc\u0103 nu a reu\u0219it s\u0103 \u00eemi actualizeze contul \u0219i s\u0103 permit\u0103 crearea de servere virtuale. Ca o cherry on top, am ata\u0219at domeniul: <noindex><a rel=\"nofollow\" href=\"http:\/\/www.citcoin.info\">www.citcoin.info<\/a><\/noindex>. Voi men\u021bine serverul activ pentru o vreme, dup\u0103 care \u00eel voi opri, deoarece costurile de \u00eenchiriere continu\u0103 s\u0103 se adune, iar monedele citcoin de pe burs\u0103 nu sunt \u00eenc\u0103 cotate) \u00cen articol voi include capturi de ecran ale demo-ului, pentru a ilustra logica de func\u021bionare. Aplica\u021bia demo poate:<\/p>\n<ul>\n<li>Ini\u021bializa blockchain-ul;<\/li>\n<li>Crea un cont (dar acum nu se poate crea un cont nou, deoarece s-a atins num\u0103rul maxim de conturi prev\u0103zut \u00een smart contract);<\/li>\n<li>Ob\u021bine lista conturilor;<\/li>\n<li>Transfera monede citcoin \u00eentre Alice, Bob \u0219i Alex;<\/li>\n<li>Ob\u021bine evenimente (dar acum nu se pot afi\u0219a evenimente, a\u0219a c\u0103 \u00een interfa\u021b\u0103 pentru simplificare scrie c\u0103 evenimentele nu sunt suportate);<\/li>\n<li>Logheaz\u0103 ac\u021biunile.<\/li>\n<\/ul>\n<p>\nMai \u00eent\u00e2i ini\u021bializ\u0103m blockchain-ul:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: ce ne cost\u0103 s\u0103 construim un PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/773ce08270f1b22e64a79fce267bb25f.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nApoi ne cre\u0103m contul, f\u0103r\u0103 s\u0103 ne zg\u00e2rci la balan\u021b\u0103:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: ce ne cost\u0103 s\u0103 construim un PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/f1cd24aedd5e9618046c5e1ab49ceede.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nOb\u021binem lista tuturor conturilor disponibile:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: ce ne cost\u0103 s\u0103 construim un PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/796f897ca1345430f755055372d03421.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAlegem expeditorul \u0219i destinatarul, ob\u021binem soldurile lor. Dac\u0103 expeditorul \u0219i destinatarul sunt acelea\u0219i, soldul s\u0103u va fi alimentat:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: ce ne cost\u0103 s\u0103 construim un PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/58eb2ed4a4bac51e0dca1b0331d7910a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n\u00cen log urm\u0103rim executarea tranzac\u021biilor:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: ce ne cost\u0103 s\u0103 construim un PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/528760998e8dc27a73c4409f55b22087.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n\u0218i cu aplica\u021bia demo cam at\u00e2t. Apoi putem verifica tranzac\u021bia noastr\u0103 \u00een blockchain:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: ce ne cost\u0103 s\u0103 construim un PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/1d6bc12f3609b118472afec31b089f09.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n\u0218i lista general\u0103 a tranzac\u021biilor:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: ce ne cost\u0103 s\u0103 construim un PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/96675fcda8088307326dadf7852e6ce7.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAstfel am finalizat cu succes implementarea PoC pentru crearea re\u021belei Citcoin. Ce mai trebuie f\u0103cut pentru ca Citcoin s\u0103 devin\u0103 o re\u021bea complet func\u021bional\u0103 pentru transferul de monede? Foarte pu\u021bin:<\/p>\n<ul>\n<li>\u00cen etapa de creare a contului, s\u0103 implement\u0103m generarea de chei private\/publice. Cheia privat\u0103 trebuie p\u0103strat\u0103 de utilizatorul contului, cheia public\u0103 \u00een blockchain.<\/li>\n<li>S\u0103 realiz\u0103m transferul de monede, \u00een care pentru identificarea utilizatorului se utilizeaz\u0103 cheia public\u0103, nu numele.<\/li>\n<li>S\u0103 cript\u0103m tranzac\u021biile care vin de la utilizator la server cu cheia sa privat\u0103.<\/li>\n<\/ul>\n<p><\/p>\n<h2>Concluzie <\/h2>\n<p>\nAm implementat re\u021beaua Citcoin cu func\u021bii: adaug\u0103 cont, ob\u021bine sold, alimenteaz\u0103-\u021bi contul, transfer\u0103 monede de la un cont la altul. A\u0219adar, c\u00e2t de mult ne-a costat construirea PoC-ului?<\/p>\n<ul>\n<li>Trebuie s\u0103 studiem blockchain-ul \u00een general \u0219i Hyperledger Fabric \u00een special;<\/li>\n<li>S\u0103 ne \u00eenv\u0103\u021b\u0103m s\u0103 folosim cloud-urile IBM sau Amazon;<\/li>\n<li>\u00cenv\u0103\u021barea limbajului de programare JS \u0219i a unui framework web;<\/li>\n<li>Dac\u0103 trebuie s\u0103 stoc\u0103m anumite date nu \u00een blockchain, ci \u00eentr-o baz\u0103 de date separat\u0103, atunci trebuie s\u0103 \u00eenv\u0103\u021b\u0103m s\u0103 ne integr\u0103m, de exemplu, cu PostgreSQL;<\/li>\n<li>\u0218i ultimul pe list\u0103, dar nu \u0219i ca importan\u021b\u0103 \u2014 f\u0103r\u0103 cuno\u0219tin\u021be de Linux \u00een lumea modern\u0103 nu ai \u0219anse!)<\/li>\n<\/ul>\n<p>\nDesigur, nu e rocket science, dar va fi nevoie de munc\u0103!<\/p>\n<h3>Sursa pe GitHub<\/h3>\n<p>\nAm pus sursele pe <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/AlexeySushkov\/Citcoin-blockchain\">GitHub<\/a><\/noindex>. Descriere scurt\u0103 a depozitului:<br \/>\nCatalog &#171;<b>server<\/b>&#187; \u2014 server Node.js<br \/>\nCatalog &#171;<b>client<\/b>&#187; \u2014 client Node.js<br \/>\nCatalog &#171;<b>blockchain<\/b>&#187; (valorile parametrilor \u0219i cheile, desigur, sunt nefunc\u021bionale \u0219i sunt prezentate doar ca exemplu):<\/p>\n<ul>\n<li>contract \u2014 sursa contractului inteligent<\/li>\n<li>wallet \u2014 cheile utilizatorului pentru utilizarea API-ului Hyperledger Fabric. <\/li>\n<li>*.cds \u2014 versiunile compilate ale contractelor inteligente<\/li>\n<li>*.json fi\u0219iere \u2014 exemple de fi\u0219iere de configurare pentru utilizarea API-ului Hyperledger Fabric<\/li>\n<\/ul>\n<p>\n<b>Este doar \u00eenceputul!<\/b><br \/>\n<br \/>Sursa: <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.2.1 - 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\/ro\/blog\/administrirovanie\/blokchejn-chto-nam-stoit-poc-postroit\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"ro_RO\" \/>\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\/ro\/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: ce ne cost\u0103 s\u0103 construim un PoC? | ProHoster","description":"Ochiul se teme, dar m\u00e2inile se g\u00e2ndesc! \u00cen articolele anterioare am discutat despre tehnologiile pe care se bazeaz\u0103 blockchain-urile (Ce ne cost\u0103 blockchain-ul.","canonical_url":"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/blokchejn-chto-nam-stoit-poc-postroit","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"ro_RO","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\/ro\/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\/ro\/wp-json\/wp\/v2\/posts\/37868","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/comments?post=37868"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts\/37868\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/media\/28421"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/media?parent=37868"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/categories?post=37868"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/tags?post=37868"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}