{"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\/pt\/blog\/administrirovanie\/blokchejn-chto-nam-stoit-poc-postroit","title":{"rendered":"Blockchain: o que nos custa construir um PoC?","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><i>Os olhos t\u00eam medo, mas as m\u00e3os co\u00e7am!<\/i><\/p>\n<p>Nos artigos anteriores, discutimos as tecnologias sobre as quais os blockchains s\u00e3o constru\u00eddos (<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/443282\/\">O que nos custa construir um blockchain?<\/a><\/noindex>) e os casos que podem ser realizados com sua ajuda (<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/449986\/\">O que nos custa criar um caso?<\/a><\/noindex>). \u00c9 hora de colocar a m\u00e3o na massa! Para a implementa\u00e7\u00e3o de pilotos e PoC (Prova de Conceito), prefiro usar nuvens, pois t\u00eam acesso de qualquer lugar do mundo e, muitas vezes, n\u00e3o \u00e9 necess\u00e1rio perder tempo na instala\u00e7\u00e3o tediosa do ambiente, pois existem configura\u00e7\u00f5es pr\u00e9-instaladas. Ent\u00e3o, vamos fazer algo simples, como uma rede para transferir moedas entre participantes, e cham\u00e1-la modestamente de CitCoin. Para isso, usaremos a nuvem da IBM e o blockchain universal Hyperledger Fabric. Primeiro, vamos entender por que o Hyperledger Fabric \u00e9 chamado de blockchain universal?<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: o que nos custa construir um 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 universal<\/h2>\n<p>\nDe maneira geral, um sistema de informa\u00e7\u00e3o universal \u00e9:<\/p>\n<ul>\n<li>Um conjunto de servidores e um n\u00facleo de software que executa a l\u00f3gica de neg\u00f3cios;<\/li>\n<li>Interfaces para intera\u00e7\u00e3o com o sistema;<\/li>\n<li>Meios para registro, autentica\u00e7\u00e3o e autoriza\u00e7\u00e3o de dispositivos\/pessoas;<\/li>\n<li>Um banco de dados que armazena dados operacionais e arquivados:<\/li>\n<\/ul>\n<p>\n<img decoding=\"async\" alt=\"Blockchain: o que nos custa construir um PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/f11fe73de54b0573d44fae903d367df9.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nA vers\u00e3o oficial sobre o que \u00e9 o Hyperledger Fabric pode ser lida em <noindex><a rel=\"nofollow\" href=\"https:\/\/www.hyperledger.org\">site<\/a><\/noindex>, e se formos resumir, o Hyperledger Fabric \u00e9 uma plataforma de c\u00f3digo aberto que permite construir blockchains privados e executar contratos inteligentes arbitr\u00e1rios, escritos nas linguagens de programa\u00e7\u00e3o JS e Go. Vamos analisar detalhadamente a arquitetura do Hyperledger Fabric e nos certificar de que este \u00e9 um sistema universal, que apenas possui especificidades na armazenagem e grava\u00e7\u00e3o de dados. A especificidade consiste no fato de que os dados, como em todos os blockchains, s\u00e3o armazenados em blocos, que s\u00e3o inclu\u00eddos no blockchain somente se os participantes chegarem a um consenso, e uma vez gravados, os dados n\u00e3o podem ser modificados ou exclu\u00eddos sem que isso seja percebido.<\/p>\n<h2>Arquitetura do Hyperledger Fabric<\/h2>\n<p>\nO diagrama apresenta a arquitetura do Hyperledger Fabric:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: o que nos custa construir um PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/7488d70b330af2bbae1db67005f22a3e.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<b>Organiza\u00e7\u00f5es <\/b> \u2014 as organiza\u00e7\u00f5es cont\u00eam peers, assim, o blockchain existe gra\u00e7as ao suporte das organiza\u00e7\u00f5es. Diferentes organiza\u00e7\u00f5es podem fazer parte de um mesmo canal.<\/p>\n<p><b>Canal <\/b> \u2014 uma estrutura l\u00f3gica que une peers em grupos, assim, define-se o blockchain. O Hyperledger Fabric pode processar simultaneamente v\u00e1rios blockchains com l\u00f3gicas de neg\u00f3cios distintas.<\/p>\n<p><b>Provedor de Servi\u00e7os de Associados (MSP)<\/b> \u2014 \u00e9 a CA (Autoridade Certificadora) para a emiss\u00e3o de identidades e atribui\u00e7\u00e3o de fun\u00e7\u00f5es. Para criar um n\u00f3, \u00e9 necess\u00e1rio interagir com o MSP.<\/p>\n<p><b>N\u00f3s pares<\/b> \u2014 verificam transa\u00e7\u00f5es, armazenam a blockchain, executam contratos inteligentes e interagem com aplicativos. Os pares possuem uma identidade (certificado digital) emitido pela MSP. Diferente da rede Bitcoin ou Ethereum, onde todos os n\u00f3s t\u00eam igualdade de direitos, no Hyperledger Fabric, os n\u00f3s desempenham diferentes pap\u00e9is:<\/p>\n<ul>\n<li>Um par pode ser <b>par endossante<\/b> (EP) e executar contratos inteligentes.<\/li>\n<li><b>Par de compromisso<\/b> (CP) \u2014 apenas armazenam dados na blockchain e atualizam o 'estado atual'.<\/li>\n<li><b>Par \u00e2ncora<\/b> (AP) \u2014 se v\u00e1rias organiza\u00e7\u00f5es est\u00e3o envolvidas na blockchain, os pares \u00e2ncoras s\u00e3o usados para a comunica\u00e7\u00e3o entre elas. Cada organiza\u00e7\u00e3o deve ter um ou mais pares \u00e2ncoras. Com o AP, qualquer par da organiza\u00e7\u00e3o pode obter informa\u00e7\u00f5es sobre todos os pares em outras organiza\u00e7\u00f5es. Para a sincroniza\u00e7\u00e3o de informa\u00e7\u00f5es entre os AP, \u00e9 utilizado o <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Gossip_protocol\">protocolo de gossip<\/a><\/noindex>.<\/li>\n<li><b>Par l\u00edder<\/b> \u2014 se uma organiza\u00e7\u00e3o tem v\u00e1rios pares, apenas o par l\u00edder receber\u00e1 blocos do servi\u00e7o de ordena\u00e7\u00e3o e os enviar\u00e1 aos outros pares. O l\u00edder pode ser definido staticamente ou selecionado dinamicamente pelos pares na organiza\u00e7\u00e3o. Para a sincroniza\u00e7\u00e3o de informa\u00e7\u00f5es sobre os l\u00edderes, tamb\u00e9m \u00e9 utilizado o protocolo de gossip.<\/li>\n<\/ul>\n<p>\n<b>Ativos <\/b> \u2014 entidades que possuem valor, armazenadas na blockchain. Mais especificamente \u2014 s\u00e3o dados chave-valor no formato JSON. Esses dados s\u00e3o os que s\u00e3o gravados na 'Blockchain'. Eles t\u00eam um hist\u00f3rico que \u00e9 mantido na blockchain e um estado atual que \u00e9 mantido no banco de dados 'estado atual'. As estruturas de dados s\u00e3o preenchidas aleatoriamente, dependendo das necessidades empresariais. N\u00e3o h\u00e1 campos obrigat\u00f3rios, a \u00fanica recomenda\u00e7\u00e3o \u00e9 que os ativos devem ter um propriet\u00e1rio e representar valor. <\/p>\n<p><b>Livro raz\u00e3o <\/b> \u2014 consiste na blockchain 'Blockchain' e no banco de dados 'Estado Atual', onde o estado atual dos ativos \u00e9 armazenado. O estado atual utiliza LevelDB ou CouchDB.<\/p>\n<p><b>Contrato inteligente<\/b> \u2014 a l\u00f3gica de neg\u00f3cios do sistema \u00e9 implementada por meio de contratos inteligentes. No Hyperledger Fabric, os contratos inteligentes s\u00e3o chamados de chaincode. Atrav\u00e9s do chaincode, ativos e transa\u00e7\u00f5es sobre eles s\u00e3o definidos. Em termos t\u00e9cnicos, contratos inteligentes s\u00e3o m\u00f3dulos de software implementados nas linguagens de programa\u00e7\u00e3o JS ou Go.<\/p>\n<p><b>Pol\u00edtica de endosse<\/b> \u2014 para cada chaincode, \u00e9 poss\u00edvel definir pol\u00edticas sobre quantos e de quem \u00e9 necess\u00e1rio esperar confirma\u00e7\u00f5es para a transa\u00e7\u00e3o. Se a pol\u00edtica n\u00e3o for definida, o padr\u00e3o utilizado \u00e9: \u201ca transa\u00e7\u00e3o deve ser confirmada por qualquer membro de qualquer organiza\u00e7\u00e3o no canal\u201d. Exemplos de pol\u00edticas:<\/p>\n<ul>\n<li>A transa\u00e7\u00e3o deve ser confirmada por qualquer administrador da organiza\u00e7\u00e3o;<\/li>\n<li>Deve ser confirmado por qualquer membro ou cliente da organiza\u00e7\u00e3o;<\/li>\n<li>Deve ser confirmado por qualquer peer da organiza\u00e7\u00e3o.<\/li>\n<\/ul>\n<p>\n<b>Servi\u00e7o de ordena\u00e7\u00e3o<\/b> \u2014 empacota transa\u00e7\u00f5es em blocos e os envia para peers no canal. Garante a entrega de mensagens a todos os peers na rede. Para sistemas industriais, utiliza-se <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/Apache_Kafka\">o corretor de mensagens Kafka<\/a><\/noindex>, para desenvolvimento e teste <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: o que nos custa construir um PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/9060864bd1002da881d7f17ef8ec0b0c.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<ul>\n<li>O aplicativo interage com o Hyperledger Fabric, usando Go, Node.js ou Java SDK;<\/li>\n<li>O cliente cria a transa\u00e7\u00e3o tx e a envia para os peers de endorsement;<\/li>\n<li>O peer verifica a assinatura do cliente, executa a transa\u00e7\u00e3o e envia a assinatura de endorsement de volta ao cliente. O chaincode \u00e9 executado apenas nos peers de endorsement, e o resultado de sua execu\u00e7\u00e3o \u00e9 enviado a todos os peers. Esse algoritmo de funcionamento \u00e9 chamado de \u2014 consenso PBFT (Practical Byzantine Fault Tolerant). Difere do <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Byzantine_fault\">BFT cl\u00e1ssico<\/a><\/noindex> no fato de que a mensagem \u00e9 enviada e se espera a confirma\u00e7\u00e3o n\u00e3o de todos os participantes, mas apenas de um conjunto espec\u00edfico;<\/li>\n<li>Depois que o cliente recebe o n\u00famero de respostas correspondente \u00e0 pol\u00edtica de endorsement, ele envia a transa\u00e7\u00e3o para o servi\u00e7o de ordena\u00e7\u00e3o;<\/li>\n<li>O servi\u00e7o de ordena\u00e7\u00e3o forma um bloco e o envia para todos os peers de compromisso. O servi\u00e7o de ordena\u00e7\u00e3o garante a grava\u00e7\u00e3o sequencial de blocos, o que exclui o chamado fork do ledger (<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/443282\/\">veja a se\u00e7\u00e3o 'Forks'<\/a><\/noindex>);<\/li>\n<li>Os peers recebem o bloco, verificam novamente a pol\u00edtica de endorsement, gravam o bloco na blockchain e alteram o estado no banco de dados 'World state'.<\/li>\n<\/ul>\n<p>\nOu seja, h\u00e1 uma separa\u00e7\u00e3o de fun\u00e7\u00f5es entre os n\u00f3s. Isso facilita a escalabilidade e seguran\u00e7a da blockchain:<\/p>\n<ul>\n<li>Os smart contracts (chaincode) s\u00e3o executados pelos peers de endorsement. Isso garante a privacidade dos smart contracts, pois n\u00e3o s\u00e3o armazenados por todos os participantes, mas apenas nos peers de endorsement.<\/li>\n<li>A ordena\u00e7\u00e3o deve funcionar rapidamente. Isso \u00e9 garantido porque a ordena\u00e7\u00e3o apenas forma o bloco e o envia para um conjunto fixo de peers l\u00edderes.<\/li>\n<li>Os peers de compromisso apenas armazenam a blockchain \u2014 podem ser muitos e n\u00e3o requerem grande pot\u00eancia nem trabalho instant\u00e2neo. <\/li>\n<\/ul>\n<p>\nPara mais informa\u00e7\u00f5es sobre as solu\u00e7\u00f5es arquitet\u00f4nicas do Hyperledger Fabric e por que ele funciona dessa maneira, veja aqui: <noindex><a rel=\"nofollow\" href=\"https:\/\/hyperledger-fabric.readthedocs.io\/en\/latest\/arch-deep-dive.html\">Origens da Arquitetura<\/a><\/noindex> ou aqui: <noindex><a rel=\"nofollow\" href=\"https:\/\/arxiv.org\/abs\/1801.10228v2\">Hyperledger Fabric: Um Sistema Operacional Distribu\u00eddo para Blockchains Permissionadas<\/a><\/noindex>.<\/p>\n<p>Portanto, o Hyperledger Fabric \u00e9 realmente um sistema vers\u00e1til que permite:<\/p>\n<ul>\n<li>Implementar l\u00f3gica de neg\u00f3cios arbitr\u00e1ria usando o mecanismo de smart contracts;<\/li>\n<li>Gravar e recuperar dados do banco de dados blockchain no formato JSON;<\/li>\n<li>Fornecer e verificar acesso \u00e0 API, utilizando a Autoridade Certificadora. <\/li>\n<\/ul>\n<p>\nAgora que entendemos um pouco sobre as especificidades do Hyperledger Fabric, vamos finalmente fazer algo \u00fatil!<\/p>\n<h2>Implantando blockchain<\/h2>\n<p><\/p>\n<h3>Formula\u00e7\u00e3o do problema<\/h3>\n<p>\nA tarefa \u00e9 implementar uma rede Citcoin com as seguintes funcionalidades: criar conta, obter saldo, recarregar conta, transferir moedas de uma conta para outra. Vamos desenhar o modelo de objeto, que ser\u00e1 implementado no smart contract. Assim, teremos contas que se identificam por nomes (name) e cont\u00eam saldo (balance), al\u00e9m de uma lista de contas. Contas e listas de contas s\u00e3o, em termos de Hyperledger Fabric, ativos. Portanto, eles t\u00eam uma hist\u00f3ria e um estado atual. Tentarei ilustrar isso claramente:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: o que nos custa construir um PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/a4f111da59bc7982b51d583857db6d5a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAs figuras superiores representam o estado atual, que \u00e9 armazenado no estado do mundo ('World state'). Abaixo, as figuras mostram a hist\u00f3ria, que \u00e9 armazenada na blockchain. O estado atual dos ativos muda por meio de transa\u00e7\u00f5es. O ativo muda apenas como um todo, portanto, como resultado da transa\u00e7\u00e3o, um novo objeto \u00e9 criado e o valor atual do ativo \u00e9 registrado na hist\u00f3ria. <\/p>\n<h3>Nuvem IBM <\/h3>\n<p>\nCriando uma conta na <noindex><a rel=\"nofollow\" href=\"https:\/\/cloud.ibm.com\">nuvem IBM<\/a><\/noindex>. Para usar a plataforma blockchain, \u00e9 necess\u00e1rio atualiz\u00e1-la para Pay-As-You-Go. Esse processo pode n\u00e3o ser r\u00e1pido, pois a IBM solicita informa\u00e7\u00f5es adicionais e as verifica manualmente. Por outro lado, posso dizer que a IBM tem bons materiais de aprendizado que permitem implantar o Hyperledger Fabric em sua nuvem. Gostei do seguinte ciclo de artigos e exemplos:<\/p>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/IBM\/Create-BlockchainNetwork-IBPV20\/blob\/master\/README.md\">Crie uma rede blockchain b\u00e1sica usando a Plataforma Blockchain<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/IBM\/SmartContractTrading-wFabric1-4-VSCodeExt\/blob\/master\/README.md\">Crie e execute um smart contract blockchain<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/IBM\/auction-events\/blob\/master\/README.md\">Emita eventos da Plataforma Blockchain<\/a><\/noindex><\/li>\n<\/ul>\n<p>\nAbaixo est\u00e3o capturas de tela da Plataforma Blockchain da IBM. Isso n\u00e3o \u00e9 um guia para criar blockchain, mas apenas uma demonstra\u00e7\u00e3o do escopo da tarefa. Assim, para nossos fins, criamos uma Organiza\u00e7\u00e3o:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: o que nos custa construir um PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/7cb30cade6315abc69f4322a2dbcd094.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nNela, criamos n\u00f3s: Orderer CA, Org1 CA, Orderer Peer:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: o que nos custa construir um PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/4a2239a9b7ded8ba5a11ffad86a35094.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nCriamos usu\u00e1rios:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: o que nos custa construir um PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/6792b12c9316f47b0cdfaf771dacc782.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nCriamos um Canal e o chamamos de citcoin:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: o que nos custa construir um PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/ea3983f209326713dcd25762c348ac96.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nNa ess\u00eancia, o Canal \u00e9 o blockchain, portanto, come\u00e7a com o bloco zero (Bloco G\u00eanesis):<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: o que nos custa construir um PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/416df6b6ef832c6550a2642592e57250.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h3>Escrevemos o 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>\nIntuitivamente, tudo aqui deve ser claro:<\/p>\n<ul>\n<li>Existem v\u00e1rias fun\u00e7\u00f5es (AddAccount, GetAccounts, SendFrom, GetBalance, RefillBalance), que ser\u00e3o chamadas pelo programa de demonstra\u00e7\u00e3o usando a API do Hyperledger Fabric.<\/li>\n<li>As fun\u00e7\u00f5es SendFrom e RefillBalance geram eventos (Event), que ser\u00e3o recebidos pelo programa de demonstra\u00e7\u00e3o.<\/li>\n<li>A fun\u00e7\u00e3o instantiate \u00e9 chamada uma vez ao instanciar o contrato inteligente. Na verdade, ela \u00e9 chamada n\u00e3o uma vez, mas sempre que a vers\u00e3o do contrato inteligente \u00e9 alterada. Portanto, inicializar a lista com um array vazio \u00e9 uma m\u00e1 ideia, pois agora, ao mudar a vers\u00e3o do contrato inteligente, perderemos a lista atual. Mas tudo bem, estou apenas aprendendo).<\/li>\n<li>Os Accounts e a lista de accounts (accounts) s\u00e3o estruturas de dados JSON. JavaScript \u00e9 utilizado para manipular os dados.<\/li>\n<li>O valor atual do asset pode ser obtido atrav\u00e9s da chamada da fun\u00e7\u00e3o getState e atualizado com putState.<\/li>\n<li>Ao criar um Account, a fun\u00e7\u00e3o AddAccount \u00e9 chamada, onde \u00e9 feita a compara\u00e7\u00e3o com o n\u00famero m\u00e1ximo de accounts na blockchain (maxAccounts = 5). E aqui h\u00e1 um erro (notaram?), que leva ao crescimento infinito do n\u00famero de accounts. Esses tipos de erros devem ser evitados)<\/li>\n<\/ul>\n<p>\nEm seguida, carregamos o contrato inteligente no Channel e o instanciamos:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: o que nos custa construir um PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/45ad234efc9838b711f96642988f073e.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nObservando a transa\u00e7\u00e3o de instala\u00e7\u00e3o do Smart Contract:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: o que nos custa construir um PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/39605b9d09468fd0c5f0557ed8b692a1.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nVejamos os detalhes sobre o nosso Channel:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: o que nos custa construir um PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/ccaf803cf34e52f77dac448f9c83e672.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nComo resultado, obtemos o seguinte esquema da rede blockchain na nuvem IBM. Tamb\u00e9m no esquema est\u00e1 presente um programa de demonstra\u00e7\u00e3o, executado na nuvem Amazon em um servidor virtual (detalhes sobre isso estar\u00e3o na pr\u00f3xima se\u00e7\u00e3o):<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: o que nos custa construir um PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/64e5c0f27d351ee3b60d2ea471a7f58c.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h2>Criando um GUI para chamadas da API do Hyperledger Fabric<\/h2>\n<p>\nO Hyperledger Fabric possui uma API que pode ser usada para:<\/p>\n<ul>\n<li>Criar channel;<\/li>\n<li>Conectar um peer ao channel;<\/li>\n<li>Instalar e instanciar contratos inteligentes no channel;<\/li>\n<li>Chamar transa\u00e7\u00f5es;<\/li>\n<li>Solicitar informa\u00e7\u00f5es na blockchain.<\/li>\n<\/ul>\n<p><\/p>\n<h3>Desenvolvendo um aplicativo<\/h3>\n<p>\nEm nosso programa de demonstra\u00e7\u00e3o, usaremos a API apenas para chamar transa\u00e7\u00f5es e solicitar informa\u00e7\u00f5es, pois j\u00e1 realizamos as outras etapas utilizando a plataforma de blockchain IBM. Estamos escrevendo o GUI, utilizando a pilha de tecnologias padr\u00e3o: Express.js + Vue.js + Node.js. Como come\u00e7ar a criar aplicativos web modernos poderia resultar em um artigo separado. Aqui deixo um link para uma s\u00e9rie de palestras que eu mais gostei: <noindex><a rel=\"nofollow\" href=\"https:\/\/youtu.be\/Fa4cRMaTDUI\">Full Stack Web App using Vue.js &amp; Express.js<\/a><\/noindex>. O resultado foi um aplicativo cliente-servidor com uma interface gr\u00e1fica familiar no estilo Material Design do Google. A API REST entre o cliente e o servidor consiste em v\u00e1rias chamadas:<\/p>\n<ul>\n<li>HyperledgerDemo\/v1\/init \u2014 inicializar a blockchain;<\/li>\n<li>HyperledgerDemo\/v1\/accounts\/list \u2014 obter a lista de todas as accounts;<\/li>\n<li>HyperledgerDemo\/v1\/account?name=Bob&amp;balance=100 \u2014 criar a account Bob;<\/li>\n<li>HyperledgerDemo\/v1\/info?account=Bob \u2014 obter informa\u00e7\u00f5es sobre a account Bob;<\/li>\n<li>HyperledgerDemo\/v1\/transaction?from=Bob&amp;to=Alice&amp;volume=2 \u2014 transferir duas moedas de Bob para Alice;<\/li>\n<li>HyperledgerDemo\/v1\/disconnect \u2014 desconectar da blockchain.<\/li>\n<\/ul>\n<p>\nColoquei a descri\u00e7\u00e3o da API com exemplos em<noindex><a rel=\"nofollow\" href=\"https:\/\/documenter.getpostman.com\/view\/7152141\/SVfTNSeb\"> o site \"Postman\"<\/a><\/noindex> \u2014 um programa amplamente conhecido para testar APIs HTTP.<\/p>\n<h3>Aplicativo demo na nuvem Amazon<\/h3>\n<p>\nEnviei o aplicativo para a Amazon, pois a IBM ainda n\u00e3o conseguiu atualizar minha conta e permitir a cria\u00e7\u00e3o de servidores virtuais. Como toque final, adicionei o dom\u00ednio: <noindex><a rel=\"nofollow\" href=\"http:\/\/www.citcoin.info\">www.citcoin.info<\/a><\/noindex>. Vou manter um pouco o servidor ligado, depois desligarei, pois os centavos pela loca\u00e7\u00e3o continuam a contar, e as moedas citcoin ainda n\u00e3o est\u00e3o listadas na exchange) Coloco capturas de tela do demo no artigo para ilustrar a l\u00f3gica de opera\u00e7\u00e3o. O aplicativo demo pode:<\/p>\n<ul>\n<li>Inicializar a blockchain;<\/li>\n<li>Criar uma Conta (mas atualmente n\u00e3o \u00e9 poss\u00edvel criar uma nova Conta, pois o n\u00famero m\u00e1ximo de contas especificado no contrato inteligente foi alcan\u00e7ado);<\/li>\n<li>Obter a lista de Contas;<\/li>\n<li>Transferir moedas citcoin entre Alice, Bob e Alex;<\/li>\n<li>Obter eventos (mas atualmente n\u00e3o \u00e9 poss\u00edvel mostrar eventos, portanto, a interface simplificada indica que eventos n\u00e3o s\u00e3o suportados);<\/li>\n<li>Registrar a\u00e7\u00f5es.<\/li>\n<\/ul>\n<p>\nPrimeiro, inicializamos a blockchain:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: o que nos custa construir um PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/773ce08270f1b22e64a79fce267bb25f.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDepois, criamos nossa conta, sem economizar no saldo:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: o que nos custa construir um PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/f1cd24aedd5e9618046c5e1ab49ceede.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nObtemos a lista de todas as contas dispon\u00edveis:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: o que nos custa construir um PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/796f897ca1345430f755055372d03421.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nSelecionamos o remetente e o destinat\u00e1rio, e obtemos seus saldos. Se o remetente e o destinat\u00e1rio forem os mesmos, ele far\u00e1 um dep\u00f3sito em sua conta:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: o que nos custa construir um PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/58eb2ed4a4bac51e0dca1b0331d7910a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nNo log, acompanhamos a execu\u00e7\u00e3o das transa\u00e7\u00f5es:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: o que nos custa construir um PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/528760998e8dc27a73c4409f55b22087.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nCom isso, encerramos a demo do programa. A seguir, \u00e9 poss\u00edvel visualizar nossa transa\u00e7\u00e3o na blockchain:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: o que nos custa construir um PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/1d6bc12f3609b118472afec31b089f09.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nE a lista geral de transa\u00e7\u00f5es:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: o que nos custa construir um PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/96675fcda8088307326dadf7852e6ce7.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAssim, conclu\u00edmos com sucesso a implementa\u00e7\u00e3o do PoC para criar a rede Citcoin. O que mais precisamos fazer para que a Citcoin se torne uma rede completa para transferir moedas? Muito pouco:<\/p>\n<ul>\n<li>Na fase de cria\u00e7\u00e3o da conta, implementar a gera\u00e7\u00e3o de chave privada\/p\u00fablica. A chave privada deve ser armazenada pelo usu\u00e1rio da conta, enquanto a p\u00fablica na blockchain.<\/li>\n<li>Realizar a transfer\u00eancia de moedas, na qual a identifica\u00e7\u00e3o do usu\u00e1rio utiliza a chave p\u00fablica em vez do nome.<\/li>\n<li>Criptografar as transa\u00e7\u00f5es do usu\u00e1rio para o servidor com sua chave privada.<\/li>\n<\/ul>\n<p><\/p>\n<h2>Conclus\u00e3o <\/h2>\n<p>\nImplementamos a rede Citcoin com as fun\u00e7\u00f5es: adicionar conta, obter saldo, recarregar sua conta, transferir moedas de uma conta para outra. Ent\u00e3o, o que precisamos para construir o PoC?<\/p>\n<ul>\n<li>Precisamos estudar a blockchain em geral e o Hyperledger Fabric em particular;<\/li>\n<li>Aprender a usar as nuvens da IBM ou Amazon;<\/li>\n<li>Aprender a linguagem de programa\u00e7\u00e3o JS e algum framework web;<\/li>\n<li>Se precisar armazenar certos dados n\u00e3o na blockchain, mas em um banco de dados separado, aprenda a integrar, por exemplo, com PostgreSQL;<\/li>\n<li>E por \u00faltimo, mas n\u00e3o menos importante \u2014 sem conhecimento de Linux, nos dias de hoje, n\u00e3o d\u00e1 para ir longe!)<\/li>\n<\/ul>\n<p>\nClaro, n\u00e3o \u00e9 ci\u00eancia de foguetes, mas vai dar trabalho!<\/p>\n<h3>C\u00f3digos-fonte no GitHub<\/h3>\n<p>\nColoquei os fontes em <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/AlexeySushkov\/Citcoin-blockchain\">GitHub<\/a><\/noindex>. Breve descri\u00e7\u00e3o do reposit\u00f3rio:<br \/>\nCat\u00e1logo &#171;<b>servidor<\/b>&#187; \u2014 Servidor Node.js<br \/>\nCat\u00e1logo &#171;<b>client<\/b>&#187; \u2014 Cliente Node.js<br \/>\nCat\u00e1logo &#171;<b>blockchain<\/b>&#187; (os valores dos par\u00e2metros e chaves, naturalmente, s\u00e3o fict\u00edcios e fornecidos apenas como exemplo):<\/p>\n<ul>\n<li>contract \u2014 fonte do smart contract<\/li>\n<li>wallet \u2014 chaves do usu\u00e1rio para usar a API do Hyperledger Fabric. <\/li>\n<li>*.cds \u2014 vers\u00f5es compiladas dos smart contracts<\/li>\n<li>*.json arquivos \u2014 exemplos de arquivos de configura\u00e7\u00e3o para uso da API do Hyperledger Fabric<\/li>\n<\/ul>\n<p>\n<b>\u00c9 apenas o come\u00e7o!<\/b><br \/>\n<br \/>Fonte: <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\/pt\/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=\"pt_PT\" \/>\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\/pt\/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: o que nos custa construir um PoC? | ProHoster","description":"Os olhos t\u00eam medo, mas as m\u00e3os co\u00e7am! Em artigos anteriores, discutimos as tecnologias que fundamentam as blockchains (O que nos custa a blockchain.","canonical_url":"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/blokchejn-chto-nam-stoit-poc-postroit","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"pt_PT","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\/pt\/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\/pt\/wp-json\/wp\/v2\/posts\/37868","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/comments?post=37868"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/posts\/37868\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/media\/28421"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/media?parent=37868"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/categories?post=37868"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/tags?post=37868"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}