{"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\/it\/blog\/administrirovanie\/blokchejn-chto-nam-stoit-poc-postroit","title":{"rendered":"Blockchain: cosa ci costerebbe costruire un PoC?","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><i>Gli occhi hanno paura, ma le mani prurito!<\/i><\/p>\n<p>Negli articoli precedenti abbiamo analizzato le tecnologie su cui si basano le blockchain (<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/443282\/\">Cosa ci vuole per costruire una blockchain?<\/a><\/noindex>) e i casi pratici che \u00e8 possibile realizzare con esse (<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/449986\/\">Quanto ci costerebbe costruire un caso?<\/a><\/noindex>). \u00c8 tempo di metterci al lavoro! Per la realizzazione di pilot e PoC (Proof of Concept) preferisco utilizzare il cloud, poich\u00e9 \u00e8 accessibile da qualsiasi punto del mondo e, spesso, non \u00e8 necessario perdere tempo con noiose installazioni dell'ambiente, dato che ci sono configurazioni preinstallate. Dunque, facciamo qualcosa di semplice, ad esempio, una rete per il trasferimento di monete tra i partecipanti e la chiamiamo modestamente Citcoin. Useremo il cloud IBM e il blockchain universale Hyperledger Fabric. Per prima cosa, vediamo perch\u00e9 Hyperledger Fabric \u00e8 chiamato blockchain universale?<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: cosa ci costerebbe costruire 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 universale<\/h2>\n<p>\nParlando in generale, un sistema informativo universale \u00e8:<\/p>\n<ul>\n<li>Un insieme di server e un nucleo software che esegue la logica di business;<\/li>\n<li>Interfacce per interagire con il sistema;<\/li>\n<li>Strumenti per la registrazione, autenticazione e autorizzazione di dispositivi\/persone;<\/li>\n<li>Un database che memorizza dati operativi e storici:<\/li>\n<\/ul>\n<p>\n<img decoding=\"async\" alt=\"Blockchain: cosa ci costerebbe costruire un PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/f11fe73de54b0573d44fae903d367df9.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nLa definizione ufficiale di cosa sia Hyperledger Fabric pu\u00f2 essere letta su <noindex><a rel=\"nofollow\" href=\"https:\/\/www.hyperledger.org\">sito<\/a><\/noindex>, e in breve, Hyperledger Fabric \u00e8 una piattaforma open-source che consente di costruire blockchain private e di eseguire contratti intelligenti scritti in linguaggi di programmazione JS e Go. Esaminiamo in dettaglio l'architettura di Hyperledger Fabric e confermiamo che si tratta di un sistema universale, il cui unico specifico \u00e8 la modalit\u00e0 di archiviazione e registrazione dei dati. La particolarit\u00e0 \u00e8 che i dati, come in tutte le blockchain, sono memorizzati in blocchi, che vengono inseriti nella blockchain solo se i partecipanti raggiungono un consenso e, dopo la registrazione, non \u00e8 possibile modificare o eliminare i dati senza che ci\u00f2 sia notato.<\/p>\n<h2>Architettura di Hyperledger Fabric<\/h2>\n<p>\nNello schema \u00e8 rappresentata l'architettura di Hyperledger Fabric:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: cosa ci costerebbe costruire un PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/7488d70b330af2bbae1db67005f22a3e.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<b>Organizzazioni <\/b> \u2014 le organizzazioni contengono peer, ci\u00f2 significa che la blockchain esiste grazie al supporto delle organizzazioni. Diverse organizzazioni possono far parte di un unico channel.<\/p>\n<p><b>Channel <\/b> \u2014 una struttura logica che unisce i peer in gruppi, definendo cos\u00ec la blockchain. Hyperledger Fabric pu\u00f2 elaborare simultaneamente pi\u00f9 blockchain con diverse logiche di business.<\/p>\n<p><b>Membership Services Provider (MSP)<\/b> \u2014 \u00e8 l'CA (Certificate Authority) per il rilascio delle identit\u00e0 e l'assegnazione dei ruoli. Per creare un nodo \u00e8 necessario interagire con l'MSP.<\/p>\n<p><b>Node peer<\/b> \u2014 controllano le transazioni, memorizzano la blockchain, eseguono smart contract e interagiscono con le applicazioni. I peer hanno un'identit\u00e0 (certificato digitale), rilasciata da MSP. A differenza della rete Bitcoin o Ethereum, dove tutti i nodi sono uguali, in Hyperledger Fabric i nodi svolgono ruoli diversi:<\/p>\n<ul>\n<li>Il peer pu\u00f2 essere <b>peer di endorsement<\/b> (EP) e eseguire smart contract.<\/li>\n<li><b>Peer di commit<\/b> (CP) \u2014 semplicemente memorizzano dati nella blockchain e aggiornano lo 'World state'.<\/li>\n<li><b>Peer di ancoraggio<\/b> (AP) \u2014 se nella blockchain partecipano pi\u00f9 organizzazioni, i peer di ancoraggio vengono utilizzati per la comunicazione tra di esse. Ogni organizzazione deve avere uno o pi\u00f9 peer di ancoraggio. Con l'AP, qualsiasi peer nell'organizzazione pu\u00f2 ottenere informazioni su tutti i peer delle altre organizzazioni. Per la sincronizzazione delle informazioni tra gli AP viene utilizzato <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Gossip_protocol\">il protocollo gossip<\/a><\/noindex>.<\/li>\n<li><b>Peer leader<\/b> \u2014 se un'organizzazione ha pi\u00f9 peer, solo il peer leader ricever\u00e0 i blocchi dal servizio di ordinamento e li distribuir\u00e0 agli altri peer. Il leader pu\u00f2 essere assegnato staticamente o selezionato dinamicamente dai peer nell'organizzazione. Anche per la sincronizzazione delle informazioni sui leader viene utilizzato il protocollo gossip.<\/li>\n<\/ul>\n<p>\n<b>Asset <\/b> \u2014 entit\u00e0 di valore memorizzate nella blockchain. Pi\u00f9 specificamente, questi sono dati chiave-valore in formato JSON. Questi dati vengono registrati nella blockchain 'Blockchain'. Hanno una storia conservata nella blockchain e uno stato attuale immagazzinato nel database 'World state'. Le strutture dei dati possono essere riempite in modo arbitrario a seconda delle esigenze aziendali. Non ci sono campi obbligatori, l'unica raccomandazione \u00e8 che gli asset debbano avere un proprietario e rappresentare valore. <\/p>\n<p><b>Registro <\/b> \u2014 \u00e8 composto dalla blockchain 'Blockchain' e dal database 'World state', in cui \u00e8 memorizzato lo stato attuale degli asset. Lo stato mondiale utilizza LevelDB o CouchDB.<\/p>\n<p><b>Smart contract<\/b> \u2014 la logica aziendale del sistema viene implementata tramite smart contract. In Hyperledger Fabric, gli smart contract sono chiamati chaincode. Con il chaincode vengono definiti asset e transazioni su di essi. In termini tecnici, gli smart contract sono moduli software implementati in linguaggi di programmazione come JS o Go.<\/p>\n<p><b>Politica di endorsement<\/b> \u2014 per ogni chaincode \u00e8 possibile definire politiche su quanti e quali potrebbero essere i membri da cui attendere conferme per una transazione. Se non viene impostata alcuna politica, viene utilizzata per impostazione predefinita: \u201cla transazione deve essere confermata da qualsiasi membro di qualsiasi organizzazione nel canale\u201d. Esempi di politiche:<\/p>\n<ul>\n<li>La transazione deve essere confermata da un amministratore dell'organizzazione;<\/li>\n<li>Deve essere confermata da un qualsiasi membro o cliente dell'organizzazione;<\/li>\n<li>Deve essere confermata da un qualsiasi peer dell'organizzazione.<\/li>\n<\/ul>\n<p>\n<b>Servizio di ordinazione<\/b> \u2014 incapsula le transazioni in blocchi e li invia ai peer nel channel. Garantisce la consegna dei messaggi a tutti i peer nella rete. Per i sistemi industriali viene utilizzato <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/Apache_Kafka\">il broker di messaggi Kafka<\/a><\/noindex>, per sviluppo e test <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: cosa ci costerebbe costruire un PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/9060864bd1002da881d7f17ef8ec0b0c.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<ul>\n<li>L'applicazione interagisce con Hyperledger Fabric utilizzando Go, Node.js o Java SDK;<\/li>\n<li>Il cliente crea una transazione tx e la invia ai peer di endorsing;<\/li>\n<li>Il peer verifica la firma del cliente, esegue la transazione e invia la firma di endorsement al cliente. Il chaincode viene eseguito solo sui peer di endorsing e il risultato della sua esecuzione viene inviato a tutti i peer. Questo algoritmo di lavoro \u00e8 chiamato consenso PBFT (Practical Byzantine Fault Tolerant). Differisce da <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Byzantine_fault\">BFT classico<\/a><\/noindex> in quanto il messaggio viene inviato e si attende una conferma non da tutti i partecipanti, ma solo da un determinato insieme;<\/li>\n<li>Dopo che il cliente ha ricevuto il numero di risposte corrispondente alla politica di endorsement, invia la transazione al servizio di ordinazione;<\/li>\n<li>Il servizio di ordinazione forma un blocco e lo invia a tutti i peer di committing. Il servizio di ordinazione garantisce una registrazione sequenziale dei blocchi, escludendo cos\u00ec, il cosiddetto fork del ledger (<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/443282\/\">vedi sezione 'Forks'<\/a><\/noindex>);<\/li>\n<li>I peer ricevono il blocco, verificano nuovamente la politica di endorsement, registrano il blocco nella blockchain e aggiornano lo stato nel database 'World state'.<\/li>\n<\/ul>\n<p>\nSi ottiene quindi una separazione dei ruoli tra i nodi. Questo assicura la scalabilit\u00e0 e la sicurezza della blockchain:<\/p>\n<ul>\n<li>I contratti intelligenti (chaincode) vengono eseguiti dai peer di endorsing. Questo garantisce la riservatezza dei contratti intelligenti, poich\u00e9 non sono memorizzati da tutti i partecipanti, ma solo sui peer di endorsing.<\/li>\n<li>Ordering deve funzionare rapidamente. Questo \u00e8 garantito dal fatto che l'Ordering forma solo il blocco e lo invia a un insieme fisso di peer leader.<\/li>\n<li>I peer di committing conservano semplicemente la blockchain \u2014 possono essere numerosi e non richiedono elevate capacit\u00e0 e prestazioni istantanee. <\/li>\n<\/ul>\n<p>\nPer saperne di pi\u00f9 sulle soluzioni architetturali di Hyperledger Fabric e sul motivo per cui funziona in questo modo, puoi consultare qui: <noindex><a rel=\"nofollow\" href=\"https:\/\/hyperledger-fabric.readthedocs.io\/en\/latest\/arch-deep-dive.html\">Origini dell'architettura<\/a><\/noindex> o qui: <noindex><a rel=\"nofollow\" href=\"https:\/\/arxiv.org\/abs\/1801.10228v2\">Hyperledger Fabric: un sistema operativo distribuito per blockchain autorizzate<\/a><\/noindex>.<\/p>\n<p>Quindi, Hyperledger Fabric \u00e8 davvero un sistema versatile, con il quale \u00e8 possibile:<\/p>\n<ul>\n<li>Implementare logiche aziendali arbitrarie utilizzando il meccanismo dei contratti intelligenti;<\/li>\n<li>Registrare e ricevere dati da un database blockchain in formato JSON;<\/li>\n<li>Fornire e verificare l'accesso all'API utilizzando una Certificazione Autorit\u00e0. <\/li>\n<\/ul>\n<p>\nOra che abbiamo compreso un po' la specificit\u00e0 di Hyperledger Fabric, facciamo finalmente qualcosa di utile!<\/p>\n<h2>Deploy del blockchain<\/h2>\n<p><\/p>\n<h3>Definizione del compito<\/h3>\n<p>\nL'attivit\u00e0 consiste nel realizzare una rete Citcoin con le seguenti funzionalit\u00e0: creare un account, ottenere un saldo, ricaricare un conto, trasferire monete da un conto all'altro. Disegniamo un modello a oggetti che implementeremo poi nel contratto intelligente. Quindi, avremo account che si identificano con nomi (name) e contengono un saldo (balance), e un elenco di account. Gli account e l'elenco degli account sono, in termini di Hyperledger Fabric, asset. Di conseguenza, hanno una storia e uno stato corrente. Prover\u00f2 a illustrarlo visivamente:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: cosa ci costerebbe costruire un PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/a4f111da59bc7982b51d583857db6d5a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nLe figure superiori rappresentano lo stato attuale, che \u00e8 memorizzato nel database \"World state\". Sotto di esse ci sono figure che mostrano la storia, che \u00e8 memorizzata nella blockchain. Lo stato attuale degli asset cambia con le transazioni. L'asset viene modificato solo integralmente, quindi a seguito dell'esecuzione della transazione viene creato un nuovo oggetto, mentre il valore corrente dell'asset va nella storia. <\/p>\n<h3>Cloud IBM <\/h3>\n<p>\nCreiamo un account in <noindex><a rel=\"nofollow\" href=\"https:\/\/cloud.ibm.com\">cloud IBM<\/a><\/noindex>. Per utilizzare la piattaforma blockchain, deve essere aggiornata a Pay-As-You-Go. Questo processo potrebbe non essere veloce, poich\u00e9 IBM richiede ulteriori informazioni e le verifica manualmente. Posso dire che IBM ha buoni materiali didattici che consentono di implementare Hyperledger Fabric nel loro cloud. Mi \u00e8 piaciuta la seguente serie di articoli ed esempi:<\/p>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/IBM\/Create-BlockchainNetwork-IBPV20\/blob\/master\/README.md\">Crea una rete blockchain di base utilizzando la Blockchain Platform<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/IBM\/SmartContractTrading-wFabric1-4-VSCodeExt\/blob\/master\/README.md\">Crea ed esegui un contratto intelligente blockchain<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/IBM\/auction-events\/blob\/master\/README.md\">Emetti eventi dalla Blockchain Platform<\/a><\/noindex><\/li>\n<\/ul>\n<p>\nDi seguito sono riportati screenshot della Blockchain Platform di IBM. Questa non \u00e8 una guida per creare un blockchain, ma solo una dimostrazione dell'ampiezza del compito. Quindi, per i nostri scopi, creiamo un'Organizzazione:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: cosa ci costerebbe costruire un PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/7cb30cade6315abc69f4322a2dbcd094.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAll'interno creiamo nodi: Orderer CA, Org1 CA, Orderer Peer:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: cosa ci costerebbe costruire un PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/4a2239a9b7ded8ba5a11ffad86a35094.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nCreiamo utenti:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: cosa ci costerebbe costruire un PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/6792b12c9316f47b0cdfaf771dacc782.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nCreiamo un Channel e lo chiamiamo citcoin:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: cosa ci costerebbe costruire un PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/ea3983f209326713dcd25762c348ac96.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nFondamentalmente, Channel \u00e8 un blockchain, quindi inizia con il blocco zero (Genesis block):<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: cosa ci costerebbe costruire un PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/416df6b6ef832c6550a2642592e57250.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h3>Scriviamo il Contratto Intelligente<\/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, qui dovrebbe essere tutto chiaro:<\/p>\n<ul>\n<li>Ci sono diverse funzioni (AddAccount, GetAccounts, SendFrom, GetBalance, RefillBalance) che saranno chiamate dal programma demo attraverso l'API di Hyperledger Fabric.<\/li>\n<li>Le funzioni SendFrom e RefillBalance generano eventi (Event) che il programma demo ricever\u00e0.<\/li>\n<li>La funzione instantiate viene chiamata una sola volta durante l'istanza del smart contract. In realt\u00e0, non viene chiamata una sola volta, ma ogni volta che viene modificata la versione del smart contract. Pertanto, inizializzare la lista con un array vuoto \u00e8 una cattiva idea, poich\u00e9 ora, al cambio della versione del smart contract, perderemo l'attuale lista. Ma non importa, sto solo imparando).<\/li>\n<li>Gli account e la lista degli account (accounts) sono strutture dati JSON. Per manipolare i dati si utilizza JS.<\/li>\n<li>Per ottenere il valore corrente dell'asset si pu\u00f2 chiamare la funzione getState, mentre per aggiornarlo si usa putState.<\/li>\n<li>Quando si crea un Account viene chiamata la funzione AddAccount, in cui si effettua un confronto con il numero massimo di account nella blockchain (maxAccounts = 5). E qui c'\u00e8 un problema (l'avete notato?), che porta a una crescita infinita del numero di account. Errori di questo tipo vanno evitati)<\/li>\n<\/ul>\n<p>\nSuccessivamente carichiamo lo smart contract nel Channel e lo istanziamo:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: cosa ci costerebbe costruire un PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/45ad234efc9838b711f96642988f073e.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nVisualizziamo la transazione per l'installazione dello Smart Contract:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: cosa ci costerebbe costruire un PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/39605b9d09468fd0c5f0557ed8b692a1.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nVisualizziamo i dettagli sul nostro Channel:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: cosa ci costerebbe costruire un PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/ccaf803cf34e52f77dac448f9c83e672.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDi conseguenza otteniamo il seguente schema della rete blockchain nel cloud IBM. Inoltre, nello schema \u00e8 presente un programma demo, eseguito nel cloud Amazon su un server virtuale (di cui parleremo nel prossimo capitolo):<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: cosa ci costerebbe costruire un PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/64e5c0f27d351ee3b60d2ea471a7f58c.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h2>Creazione di un GUI per le chiamate dell'API Hyperledger Fabric<\/h2>\n<p>\nHyperledger Fabric ha un'API che pu\u00f2 essere utilizzata per:<\/p>\n<ul>\n<li>Creare un channel;<\/li>\n<li>Collegare un peer al channel;<\/li>\n<li>Installare e istanziare smart contracts nel channel;<\/li>\n<li>Chiamare transazioni;<\/li>\n<li>Richiedere informazioni nella blockchain.<\/li>\n<\/ul>\n<p><\/p>\n<h3>Sviluppo dell'app<\/h3>\n<p>\nNella nostra applicazione demo utilizzeremo l'API solo per chiamare transazioni e richiedere informazioni, poich\u00e9 gli altri passaggi sono gi\u00e0 stati effettuati utilizzando la piattaforma blockchain IBM. Scriviamo il GUI utilizzando il stack tecnologico standard: Express.js + Vue.js + Node.js. Riguardo a come iniziare a creare moderne web application si potrebbe scrivere un articolo a parte. Qui lascio un link a una serie di lezioni che mi \u00e8 piaciuta di pi\u00f9: <noindex><a rel=\"nofollow\" href=\"https:\/\/youtu.be\/Fa4cRMaTDUI\">Full Stack Web App using Vue.js &amp; Express.js<\/a><\/noindex>. Il risultato \u00e8 stata un'applicazione client-server con un'interfaccia grafica familiare nello stile Material Design di Google. L'API REST tra il client e il server consiste in diverse chiamate:<\/p>\n<ul>\n<li>HyperledgerDemo\/v1\/init \u2014 inizializzare la blockchain;<\/li>\n<li>HyperledgerDemo\/v1\/accounts\/list \u2014 ottenere la lista di tutti gli account;<\/li>\n<li>HyperledgerDemo\/v1\/account?name=Bob&amp;balance=100 \u2014 creare l'account Bob;<\/li>\n<li>HyperledgerDemo\/v1\/info?account=Bob \u2014 ottenere informazioni sull'account Bob;<\/li>\n<li>HyperledgerDemo\/v1\/transaction?from=Bob&amp;to=Alice&amp;volume=2 \u2014 trasferire due monete da Bob a Alice;<\/li>\n<li>HyperledgerDemo\/v1\/disconnect \u2014 chiudere la connessione con la blockchain.<\/li>\n<\/ul>\n<p>\nHo caricato la descrizione dell'API con esempi su<noindex><a rel=\"nofollow\" href=\"https:\/\/documenter.getpostman.com\/view\/7152141\/SVfTNSeb\"> sito \"Postman\"<\/a><\/noindex> \u2014 un programma ampiamente conosciuto per il test delle API HTTP.<\/p>\n<h3>Demo app nel cloud di Amazon<\/h3>\n<p>\nHo caricato l'app su Amazon, poich\u00e9 IBM non \u00e8 ancora riuscita ad aggiornare il mio account e a consentire la creazione di server virtuali. Ho aggiunto come ciliegina sulla torta il dominio: <noindex><a rel=\"nofollow\" href=\"http:\/\/www.citcoin.info\">www.citcoin.info<\/a><\/noindex>. Terr\u00f2 il server acceso un po', poi lo spegner\u00f2, poich\u00e9 i costi per l'affitto continuano a crescere, e le monete citcoin non sono ancora quotate in borsa) Nella mia articolo includo screenshot del demo per chiarire la logica di funzionamento. L'app demo pu\u00f2:<\/p>\n<ul>\n<li>Inizializzare la blockchain;<\/li>\n<li>Creare un Account (ma al momento non \u00e8 possibile creare un nuovo Account, poich\u00e9 \u00e8 stato raggiunto il numero massimo di account, definito nel contratto intelligente);<\/li>\n<li>Ottenere l'elenco degli Account;<\/li>\n<li>Trasferire monete citcoin tra Alice, Bob e Alex;<\/li>\n<li>Ricevere eventi (ma attualmente non \u00e8 possibile mostrare eventi, quindi l'interfaccia per semplicit\u00e0 indica che gli eventi non sono supportati);<\/li>\n<li>Registrare le azioni.<\/li>\n<\/ul>\n<p>\nPer prima cosa inizializziamo la blockchain:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: cosa ci costerebbe costruire un PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/773ce08270f1b22e64a79fce267bb25f.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nPoi creiamo il nostro account, senza badare al saldo:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: cosa ci costerebbe costruire un PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/f1cd24aedd5e9618046c5e1ab49ceede.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nOttenere l'elenco di tutti gli account disponibili:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: cosa ci costerebbe costruire un PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/796f897ca1345430f755055372d03421.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nSelezioniamo il mittente e il destinatario, otteniamo i loro saldi. Se il mittente e il destinatario sono lo stesso, il suo saldo verr\u00e0 ricaricato:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: cosa ci costerebbe costruire un PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/58eb2ed4a4bac51e0dca1b0331d7910a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nNel log monitoriamo l'esecuzione delle transazioni:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: cosa ci costerebbe costruire un PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/528760998e8dc27a73c4409f55b22087.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nIn realt\u00e0, con la demo program, abbiamo concluso. Successivamente, possiamo vedere la nostra transazione nella blockchain:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: cosa ci costerebbe costruire un PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/1d6bc12f3609b118472afec31b089f09.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nE l'elenco generale delle transazioni:<\/p>\n<p><img decoding=\"async\" alt=\"Blockchain: cosa ci costerebbe costruire un PoC?\" src=\"\/wp-content\/uploads\/2019\/09\/96675fcda8088307326dadf7852e6ce7.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nCos\u00ec abbiamo completato con successo l'implementazione del PoC per la creazione della rete Citcoin. Cosa resta da fare affinch\u00e9 Citcoin diventi una rete completa per il trasferimento di monete? Davvero poco:<\/p>\n<ul>\n<li>Nella fase di creazione dell'account implementare la generazione della chiave privata\/pubblica. La chiave privata dovrebbe essere conservata dall'utente dell'account, quella pubblica nella blockchain.<\/li>\n<li>Eseguire un trasferimento di monete in cui per identificare l'utente venga utilizzata non il nome, ma la chiave pubblica.<\/li>\n<li>Cifrare le transazioni che vanno dall'utente al server con la sua chiave privata.<\/li>\n<\/ul>\n<p><\/p>\n<h2>Conclusione <\/h2>\n<p>\nAbbiamo realizzato la rete Citcoin con le funzionalit\u00e0: aggiungere account, ottenere saldo, ricaricare il proprio conto, trasferire monete da un conto all'altro. Quindi, cosa ci \u00e8 costato costruire il PoC?<\/p>\n<ul>\n<li>Dobbiamo studiare la blockchain in generale e Hyperledger Fabric in particolare;<\/li>\n<li>Imparare a utilizzare i cloud IBM o Amazon;<\/li>\n<li>Imparare il linguaggio di programmazione JS e qualche framework web;<\/li>\n<li>Se alcuni dati devono essere memorizzati non nella blockchain, ma in un database separato, \u00e8 necessario imparare a integrarsi, ad esempio, con PostgreSQL;<\/li>\n<li>E ultimo nella lista, ma non per importanza \u2014 senza la conoscenza di Linux nel mondo moderno non si va da nessuna parte!)<\/li>\n<\/ul>\n<p>\nCerto, non \u00e8 una scienza missilistica, ma si dovr\u00e0 sudare un po'!<\/p>\n<h3>Sorgenti su GitHub<\/h3>\n<p>\nHo posizionato i file sorgente su <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/AlexeySushkov\/Citcoin-blockchain\">GitHub<\/a><\/noindex>. Descrizione breve del repository:<br \/>\nCatalogo &#171;<b>server<\/b>&#187; \u2014 server Node.js<br \/>\nCatalogo &#171;<b>client<\/b>&#187; \u2014 client Node.js<br \/>\nCatalogo &#171;<b>blockchain<\/b>&#187; (i valori dei parametri e le chiavi, ovviamente, non funzionano e sono forniti solo come esempio):<\/p>\n<ul>\n<li>contract \u2014 sorgente del contratto intelligente<\/li>\n<li>wallet \u2014 chiavi dell'utente per utilizzare l'API di Hyperledger Fabric. <\/li>\n<li>*.cds \u2014 versioni compile dei contratti intelligenti<\/li>\n<li>*.json file \u2014 esempi di file di configurazione per l'uso dell'API di Hyperledger Fabric<\/li>\n<\/ul>\n<p>\n<b>\u00c8 solo l'inizio!<\/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.1.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\/it\/blog\/administrirovanie\/blokchejn-chto-nam-stoit-poc-postroit\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"it_IT\" \/>\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\/it\/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: cosa ci costa costruire un PoC? | ProHoster","description":"Gli occhi hanno paura, ma le mani prurito! Negli articoli precedenti abbiamo esaminato le tecnologie su cui si basano le blockchain (Cosa ci costa una blockchain.","canonical_url":"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/blokchejn-chto-nam-stoit-poc-postroit","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"it_IT","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\/it\/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\/it\/wp-json\/wp\/v2\/posts\/37868","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/comments?post=37868"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts\/37868\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/media\/28421"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/media?parent=37868"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/categories?post=37868"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/tags?post=37868"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}