Blockchain : que nous coûte-t-il de construire un PoC ?

Les yeux ont peur, mais les mains démangent !

Dans les articles prĂ©cĂ©dents, nous avons explorĂ© les technologies sur lesquelles reposent les blockchains (Quel est le coĂ»t de construire une blockchain ?) et les cas d'utilisation qui peuvent ĂȘtre rĂ©alisĂ©s grĂące Ă  elles (Qu'est-ce qui nous empĂȘche de construire un cas ?). Il est temps de mettre la main Ă  la pĂąte ! Pour rĂ©aliser des pilotes et des PoC (Proof of Concept), je prĂ©fĂšre utiliser le cloud, car ils sont accessibles de n'importe oĂč dans le monde et, souvent, il n'est pas nĂ©cessaire de perdre du temps sur une installation ennuyeuse, car il existe des configurations prĂ©dĂ©finies. Alors, faisons quelque chose de simple, par exemple, un rĂ©seau pour transfĂ©rer des piĂšces entre participants et appelons-le modestement Cittcoin. Pour cela, nous allons utiliser le cloud IBM et la blockchain universelle Hyperledger Fabric. Commençons par comprendre pourquoi Hyperledger Fabric est appelĂ© blockchain universelle.

Blockchain : que nous coûte-t-il de construire un PoC ?

Hyperledger Fabric — blockchain universelle

En général, un systÚme d'information universel se compose de :

  • Un ensemble de serveurs et un cƓur logiciel exĂ©cutant la logique mĂ©tier ;
  • Interfaces pour interagir avec le systĂšme ;
  • Outils pour enregistrer, authentifier et autoriser les dispositifs / personnes ;
  • Une base de donnĂ©es qui stocke les donnĂ©es opĂ©rationnelles et archivĂ©es :

Blockchain : que nous coûte-t-il de construire un PoC ?

La version officielle de ce qu'est Hyperledger Fabric peut ĂȘtre consultĂ©e sur site, et en rĂ©sumĂ©, Hyperledger Fabric est une plateforme open source permettant de construire des blockchains privĂ©es et d'exĂ©cuter des contrats intelligents arbitrĂ©s dans des langages de programmation comme JS et Go. Analysons de plus prĂšs l'architecture d'Hyperledger Fabric et vĂ©rifions que c'est un systĂšme universel, oĂč il n'y a que des spĂ©cificitĂ©s sur le stockage et l'enregistrement des donnĂ©es. La spĂ©cificitĂ© rĂ©side dans le fait que les donnĂ©es, comme dans tous les blockchains, sont stockĂ©es dans des blocs, qui ne peuvent ĂȘtre ajoutĂ©s Ă  la blockchain que si les participants parviennent Ă  un consensus, et une fois enregistrĂ©es, les donnĂ©es ne peuvent pas ĂȘtre modifiĂ©es ou supprimĂ©es furtivement.

Architecture d'Hyperledger Fabric

Le schéma montre l'architecture d'Hyperledger Fabric :

Blockchain : que nous coûte-t-il de construire un PoC ?

Organisations — les organisations contiennent des pairs, de sorte que la blockchain existe grĂące au soutien des organisations. DiffĂ©rentes organisations peuvent faire partie d'un mĂȘme canal.

Channel — une structure logique qui regroupe des pairs, dĂ©finissant ainsi la blockchain. Hyperledger Fabric peut traiter simultanĂ©ment plusieurs blockchains avec diffĂ©rentes logiques mĂ©tier.

Fournisseur de services d'adhĂ©sion (MSP) — c'est une CA (AutoritĂ© de certification) pour l'Ă©mission d'identitĂ©s et l'attribution de rĂŽles. Pour crĂ©er un nƓud, il est nĂ©cessaire d'interagir avec le MSP.

NƓuds pairs — vĂ©rifient les transactions, stockent la blockchain, exĂ©cutent des contrats intelligents et interagissent avec des applications. Les pairs ont une identitĂ© (certificat numĂ©rique) dĂ©livrĂ©e par un MSP. Contrairement au rĂ©seau Bitcoin ou Ethereum, oĂč tous les nƓuds sont Ă©gaux, dans Hyperledger Fabric, les nƓuds jouent des rĂŽles diffĂ©rents :

  • Le pair peut ĂȘtre un pair d'approbation (EP) et exĂ©cuter des contrats intelligents.
  • Le pair d'engagement (CP) — sauvegarde uniquement les donnĂ©es dans la blockchain et actualise l'Ă©tat mondial.
  • Pair d'ancrage (AP) — si plusieurs organisations participent Ă  la blockchain, les pairs d'ancrage sont utilisĂ©s pour Ă©tablir des liens entre elles. Chaque organisation doit avoir un ou plusieurs pairs d'ancrage. GrĂące Ă  l'AP, tout pair d'une organisation peut obtenir des informations sur tous les pairs des autres organisations. Pour synchroniser les informations entre les AP, le protocole de gossip.
  • Pair leader — si une organisation a plusieurs pairs, seul le pair leader recevra des blocs du service de commande et les distribuera aux autres pairs. Le leader peut ĂȘtre assignĂ© statiquement ou ĂȘtre choisi dynamiquement par les pairs de l'organisation. Pour synchroniser les informations sur les leaders, le protocole de gossip est Ă©galement utilisĂ©.

Actifs — entitĂ©s ayant de la valeur, stockĂ©es dans la blockchain. Plus prĂ©cisĂ©ment, ce sont des donnĂ©es clĂ©-valeur au format JSON. Ce sont ces donnĂ©es qui sont enregistrĂ©es dans la blockchain «Blockchain». Elles ont une histoire, qui est conservĂ©e dans la blockchain, et un Ă©tat actuel qui est stockĂ© dans la base de donnĂ©es «World state». Les structures de donnĂ©es sont remplies alĂ©atoirement selon les exigences commerciales. Il n'y a pas de champs obligatoires, la seule recommandation est que les actifs doivent avoir un propriĂ©taire et reprĂ©senter de la valeur.

Grand livre — composĂ© de la blockchain «Blockchain» et de la base de donnĂ©es «World state», dans laquelle l'Ă©tat actuel des actifs est stockĂ©. L'Ă©tat mondial utilise LevelDB ou CouchDB.

Contrat intelligent — la logique commerciale du systĂšme est implĂ©mentĂ©e Ă  l'aide de contrats intelligents. Dans Hyperledger Fabric, les contrats intelligents sont appelĂ©s chaincode. Avec le chaincode, les actifs et les transactions qui leur sont associĂ©es sont dĂ©finis. En termes techniques, les contrats intelligents sont des modules logiciels rĂ©alisĂ©s dans les langages de programmation JS ou Go.

Politique d'approbation — pour chaque chaincode, il est possible de dĂ©finir des politiques concernant le nombre et les membres dont les confirmations sont nĂ©cessaires pour une transaction. Si aucune politique n'est dĂ©finie, la rĂšgle par dĂ©faut est : "la transaction doit ĂȘtre approuvĂ©e par tout membre (member) de n'importe quelle organisation dans le canal". Exemples de politiques :

  • La transaction doit ĂȘtre approuvĂ©e par n'importe quel administrateur de l'organisation ;
  • Doit ĂȘtre approuvĂ©e par tout membre ou client de l'organisation ;
  • Doit ĂȘtre approuvĂ©e par tout peer de l'organisation.

Service de commande — emballe les transactions dans des blocs et les envoie aux peers dans le channel. Garantit la livraison des messages Ă  tous les peers du rĂ©seau. Pour les systĂšmes industriels, on utilise le courtier de messages Kafka, pour le dĂ©veloppement et les tests. Solo.

CallFlow

Blockchain : que nous coûte-t-il de construire un PoC ?

  • L'application interagit avec Hyperledger Fabric en utilisant les SDK Go, Node.js ou Java ;
  • Le client crĂ©e une transaction tx et l'envoie aux endorsing peers ;
  • Le peer vĂ©rifie la signature du client, exĂ©cute la transaction et renvoie la signature d'endossement au client. Le chaincode n'est exĂ©cutĂ© que sur l'endorsing peer, et le rĂ©sultat de son exĂ©cution est diffusĂ© Ă  tous les peers. Ce mĂ©canisme de fonctionnement est appelĂ© — consensus PBFT (Practical Byzantine Fault Tolerant). Il se distingue de la BFT classique en ce sens que le message est diffusĂ© et qu'une confirmation est attendue non pas de tous les participants, mais seulement d'un ensemble spĂ©cifique ;
  • AprĂšs que le client a reçu un nombre de rĂ©ponses correspondant Ă  la politique d'endossement, il envoie la transaction au service de commande ;
  • Le service de commande forme un bloc et l'envoie Ă  tous les committing peers. Le service de commande assure l'enregistrement sĂ©quentiel des blocs, ce qui exclut ce qu'on appelle le fork du ledger (voir la section « Forks »);
  • Les peers reçoivent le bloc, vĂ©rifient de nouveau la politique d'endossement, enregistrent le bloc dans la blockchain et modifient l'Ă©tat dans la base de donnĂ©es « World state ».

C'est-Ă -dire qu'il y a une sĂ©paration des rĂŽles entre les nƓuds. Cela assure l'Ă©volutivitĂ© et la sĂ©curitĂ© de la blockchain :

  • Les smart contracts (chaincode) sont exĂ©cutĂ©s par les endorsing peers. Cela assure la confidentialitĂ© des smart contracts, car ils ne sont pas stockĂ©s par tous les participants, mais seulement sur les endorsing peers.
  • Le service de commande doit fonctionner rapidement. Cela est assurĂ© par le fait que le service de commande ne fait que former un bloc et l'envoyer Ă  un ensemble fixe de leader peers.
  • Les committing peers stockent simplement la blockchain — ils peuvent ĂȘtre nombreux et ne nĂ©cessitent pas une grande puissance et un fonctionnement instantanĂ©.

Pour plus de détails sur les solutions architecturales d'Hyperledger Fabric et pourquoi il fonctionne ainsi, vous pouvez consulter ici : Origines de l'architecture ou ici : Hyperledger Fabric : un systÚme d'exploitation distribué pour blockchains autorisées.

Ainsi, Hyperledger Fabric est vraiment un systĂšme polyvalent, qui permet de :

  • RĂ©aliser une logique commerciale arbitraire en utilisant le mĂ©canisme des smart contracts ;
  • Enregistrer et rĂ©cupĂ©rer des donnĂ©es depuis une base de donnĂ©es blockchain au format JSON;
  • Fournir et vĂ©rifier l'accĂšs Ă  l'API en utilisant une autoritĂ© de certification.

Maintenant que nous avons un peu compris la spécificité d'Hyperledger Fabric, faisons enfin quelque chose d'utile!

Déploiement de la blockchain

Définition du problÚme

La tùche consiste à implémenter un réseau Citcoin avec les fonctionnalités suivantes : créer un compte, obtenir un solde, approvisionner un compte, transférer des piÚces d'un compte à un autre. Dessinons un modÚle d'objet que nous allons ensuite implémenter dans un contrat intelligent. Ainsi, nous aurons des comptes qui s'identifient par des noms (name) et contiennent un solde (balance), ainsi qu'une liste de comptes. Les comptes et la liste de comptes sont des actifs en termes d'Hyperledger Fabric. Par conséquent, ils ont une histoire et un état actuel. Je vais essayer de le dessiner visuellement :

Blockchain : que nous coûte-t-il de construire un PoC ?

Les figures supĂ©rieures reprĂ©sentent l'Ă©tat actuel, qui est stockĂ© dans la base « World state ». En dessous, les figures montrent l'historique qui est conservĂ© dans la blockchain. L'Ă©tat actuel des actifs est modifiĂ© par des transactions. Un actif ne peut ĂȘtre modifiĂ© que dans son intĂ©gralitĂ©, donc Ă  la suite d'une transaction, un nouvel objet est créé et la valeur actuelle de l'actif est envoyĂ©e dans l'historique.

Cloud IBM

Créons un compte dans le cloud IBM. Pour utiliser la plateforme blockchain, il faut la mettre à niveau vers Pay-As-You-Go. Ce processus peut prendre du temps, car IBM demande des informations supplémentaires et les vérifie manuellement. En positif, je peux dire qu'IBM a de bons matériaux d'apprentissage, permettant de déployer Hyperledger Fabric dans leur cloud. J'ai apprécié le cycle suivant d'articles et d'exemples :

Voici quelques captures d'écran de la plateforme Blockchain d'IBM. Ce n'est pas un guide sur la création d'une blockchain, mais simplement une démonstration de l'ampleur de la tùche. Alors, pour nos besoins, créons une Organisation :

Blockchain : que nous coûte-t-il de construire un PoC ?

Nous y crĂ©ons des nƓuds : Orderer CA, Org1 CA, Orderer Peer :

Blockchain : que nous coûte-t-il de construire un PoC ?

Créons des utilisateurs :

Blockchain : que nous coûte-t-il de construire un PoC ?

Créons un Canal et appelons-le citcoin :

Blockchain : que nous coûte-t-il de construire un PoC ?

En substance, un Canal est une blockchain, donc il commence avec le bloc zéro (Genesis block) :

Blockchain : que nous coûte-t-il de construire un PoC ?

Écrivons un Smart Contract

/*
 * Citcoin smart-contract v1.5 for Hyperledger Fabric
 * (c) Alexey Sushkov, 2019
 */
 
'use strict';
 
const { Contract } = require('fabric-contract-api');
const maxAccounts = 5;
 
class CitcoinEvents extends Contract {
 
    async instantiate(ctx) {
        console.info('instantiate');
        let emptyList = [];
        await ctx.stub.putState('accounts', Buffer.from(JSON.stringify(emptyList)));
    }
    // Get all accounts
    async GetAccounts(ctx) {
        // Get account list:
        let accounts = '{}'
        let accountsData = await ctx.stub.getState('accounts');
        if (accountsData) {
            accounts = JSON.parse(accountsData.toString());
        } else {
            throw new Error('accounts not found');
        }
        return accountsData.toString()
    }
     // add a account object to the blockchain state identifited by their name
    async AddAccount(ctx, name, balance) {
        // this is account data:
        let account = {
            name: name,
            balance: Number(balance),       
            type: 'account',
        };
        // create account:
        await ctx.stub.putState(name, Buffer.from(JSON.stringify(account)));
 
        // Add account to list:
        let accountsData = await ctx.stub.getState('accounts');
        if (accountsData) {
            let accounts = JSON.parse(accountsData.toString());
            if (accounts.length < maxAccounts)
            {
                accounts.push(name);
                await ctx.stub.putState('accounts', Buffer.from(JSON.stringify(accounts)));
            } else {
                throw new Error('Max accounts number reached');
            }
        } else {
            throw new Error('accounts not found');
        }
        // return  object
        return JSON.stringify(account);
    }
    // Sends money from Account to Account
    async SendFrom(ctx, fromAccount, toAccount, value) {
        // get Account from
        let fromData = await ctx.stub.getState(fromAccount);
        let from;
        if (fromData) {
            from = JSON.parse(fromData.toString());
            if (from.type !== 'account') {
                throw new Error('wrong from type');
            }   
        } else {
            throw new Error('Accout from not found');
        }
        // get Account to
        let toData = await ctx.stub.getState(toAccount);
        let to;
        if (toData) {
            to = JSON.parse(toData.toString());
            if (to.type !== 'account') {
                throw new Error('wrong to type');
            }  
        } else {
            throw new Error('Accout to not found');
        }
 
        // update the balances
        if ((from.balance - Number(value)) >= 0 ) {
            from.balance -= Number(value);
            to.balance += Number(value);
        } else {
            throw new Error('From Account: not enought balance');          
        }
 
        await ctx.stub.putState(from.name, Buffer.from(JSON.stringify(from)));
        await ctx.stub.putState(to.name, Buffer.from(JSON.stringify(to)));
                 
        // define and set Event
        let Event = {
            type: "SendFrom",
            from: from.name,
            to: to.name,
            balanceFrom: from.balance,
            balanceTo: to.balance,
            value: value
        };
        await ctx.stub.setEvent('SendFrom', Buffer.from(JSON.stringify(Event)));
 
        // return to object
        return JSON.stringify(from);
    }
 
    // get the state from key
    async GetState(ctx, key) {
        let data = await ctx.stub.getState(key);
        let jsonData = JSON.parse(data.toString());
        return JSON.stringify(jsonData);
    }
    // GetBalance   
    async GetBalance(ctx, accountName) {
        let data = await ctx.stub.getState(accountName);
        let jsonData = JSON.parse(data.toString());
        return JSON.stringify(jsonData);
    }
     
    // Refill own balance
    async RefillBalance(ctx, toAccount, value) {
        // get Account to
        let toData = await ctx.stub.getState(toAccount);
        let to;
        if (toData) {
            to = JSON.parse(toData.toString());
            if (to.type !== 'account') {
                throw new Error('wrong to type');
            }  
        } else {
            throw new Error('Accout to not found');
        }
 
        // update the balance
        to.balance += Number(value);
        await ctx.stub.putState(to.name, Buffer.from(JSON.stringify(to)));
                 
        // define and set Event
        let Event = {
            type: "RefillBalance",
            to: to.name,
            balanceTo: to.balance,
            value: value
        };
        await ctx.stub.setEvent('RefillBalance', Buffer.from(JSON.stringify(Event)));
 
        // return to object
        return JSON.stringify(from);
    }
}
module.exports = CitcoinEvents;

Intuitivement, tout devrait ĂȘtre clair ici :

  • Il existe plusieurs fonctions (AddAccount, GetAccounts, SendFrom, GetBalance, RefillBalance) qui seront appelĂ©es par le programme de dĂ©monstration Ă  l'aide de l'API Hyperledger Fabric.
  • Les fonctions SendFrom et RefillBalance gĂ©nĂšrent des Ă©vĂ©nements (Event) que recevra le programme de dĂ©monstration.
  • La fonction instantiate est appelĂ©e une fois lors de l'instanciation d'un smart contract. En rĂ©alitĂ©, elle est appelĂ©e plusieurs fois lors de chaque changement de version du smart contract. Par consĂ©quent, initialiser la liste avec un tableau vide est une mauvaise idĂ©e, car lors du changement de version, nous perdrons la liste actuelle. Mais pas de souci, je suis simplement en train d'apprendre).
  • Les comptes et la liste des comptes (accounts) sont des structures de donnĂ©es JSON. Le JS est utilisĂ© pour manipuler les donnĂ©es.
  • La valeur actuelle de l'asset peut ĂȘtre obtenue en appelant la fonction getState, et mise Ă  jour avec putState.
  • Lors de la crĂ©ation d'un compte, la fonction AddAccount est appelĂ©e, oĂč une comparaison avec le nombre maximum de comptes dans la blockchain (maxAccounts = 5) est effectuĂ©e. Et ici, il y a une erreur (vous l'avez remarquĂ© ?), qui entraĂźne une croissance infinie du nombre de comptes. De telles erreurs doivent ĂȘtre Ă©vitĂ©es)

Nous continuons en chargeant le smart contract dans le channel et en l'instanciant :

Blockchain : que nous coûte-t-il de construire un PoC ?

Nous regardons la transaction d'installation du Smart Contract :

Blockchain : que nous coûte-t-il de construire un PoC ?

Nous consultons les détails de notre Channel :

Blockchain : que nous coûte-t-il de construire un PoC ?

En conséquence, nous obtenons le schéma suivant du réseau blockchain dans le cloud IBM. Le schéma présente également un programme démo, exécuté dans le cloud Amazon sur un serveur virtuel (nous en parlerons plus en détail dans la section suivante) :

Blockchain : que nous coûte-t-il de construire un PoC ?

Création d'une interface graphique pour les appels à l'API Hyperledger Fabric

Hyperledger Fabric dispose d'une API qui peut ĂȘtre utilisĂ©e pour :

  • CrĂ©er un channel ;
  • Connecter un peer au channel ;
  • Installer et instancier des smart contracts dans le channel ;
  • Appeler des transactions ;
  • Demander des informations dans la blockchain.

Développement d'application

Dans notre programme démo, nous utiliserons l'API uniquement pour appeler des transactions et demander des informations, car nous avons déjà réalisé les autres étapes en utilisant la plateforme blockchain IBM. Nous écrivons l'interface graphique en utilisant la pile technologique standard : Express.js + Vue.js + Node.js. On pourrait écrire un article séparé sur la façon de commencer à créer des applications web modernes. Ici, je laisse un lien vers une série de conférences que j'ai le plus appréciées : Full Stack Web App using Vue.js & Express.js. En conséquence, cela a donné une application client-serveur avec une interface graphique familiÚre dans le style Material Design de Google. L'API REST entre le client et le serveur se compose de plusieurs appels :

  • HyperledgerDemo/v1/init — initialiser la blockchain ;
  • HyperledgerDemo/v1/accounts/list — obtenir la liste de tous les comptes ;
  • HyperledgerDemo/v1/account?name=Bob&balance=100 — crĂ©er le compte Bob ;
  • HyperledgerDemo/v1/info?account=Bob — obtenir des informations sur le compte Bob ;
  • HyperledgerDemo/v1/transaction?from=Bob&to=Alice&volume=2 — transfĂ©rer deux piĂšces de Bob Ă  Alice ;
  • HyperledgerDemo/v1/disconnect — fermer la connexion avec la blockchain.

J'ai mis la description de l'API avec des exemples sur le site «Postman» — un programme bien connu pour tester les API HTTP.

L'application de démonstration est hébergée sur Amazon Cloud.

J'ai téléchargé l'application sur Amazon, car IBM n'a toujours pas réussi à mettre à jour mon compte et à me permettre de créer des serveurs virtuels. En prime, j'ai ajouté le domaine : www.citcoin.info. Je garderai le serveur allumé un peu, puis je l'éteindrai, car les frais de location s'accumulent et les piÚces de citcoin ne sont pas encore cotées sur les échanges.) Dans cet article, je mets des captures d'écran de la démonstration pour illustrer la logique de fonctionnement. L'application de démonstration peut :

  • Initialiser la blockchain ;
  • CrĂ©er un compte (mais actuellement, il n'est pas possible de crĂ©er un nouveau compte, car le nombre maximal de comptes mentionnĂ© dans le contrat intelligent a Ă©tĂ© atteint) ;
  • Obtenir la liste des comptes ;
  • TransfĂ©rer des piĂšces de citcoin entre Alice, Bob et Alex ;
  • Recevoir des Ă©vĂ©nements (mais pour l'instant, il n'est pas possible d'afficher des Ă©vĂ©nements, donc pour simplifier l'interface, il est indiquĂ© que les Ă©vĂ©nements ne sont pas pris en charge) ;
  • Enregistrer les actions.

D'abord, nous initialisons la blockchain :

Blockchain : que nous coûte-t-il de construire un PoC ?

Ensuite, nous créons notre propre compte, sans lésiner sur le solde :

Blockchain : que nous coûte-t-il de construire un PoC ?

Nous obtenons la liste de tous les comptes disponibles :

Blockchain : que nous coûte-t-il de construire un PoC ?

Nous choisissons l'expĂ©diteur et le destinataire, et nous obtenons leurs soldes. Si l'expĂ©diteur et le destinataire sont la mĂȘme personne, son solde sera approvisionnĂ© :

Blockchain : que nous coûte-t-il de construire un PoC ?

Dans le log, nous suivons l'exécution des transactions :

Blockchain : que nous coûte-t-il de construire un PoC ?

Voilà, c'est tout pour l'application de démonstration. Ensuite, nous pouvons consulter notre transaction dans la blockchain :

Blockchain : que nous coûte-t-il de construire un PoC ?

Et la liste générale des transactions :

Blockchain : que nous coûte-t-il de construire un PoC ?

Nous avons rĂ©ussi Ă  terminer la mise en Ɠuvre de la PoC pour la crĂ©ation du rĂ©seau Citcoin. Que faut-il encore faire pour que Citcoin devienne un rĂ©seau complet pour le transfert de piĂšces ? Pas grand-chose :

  • Lors de la crĂ©ation du compte, mettre en place la gĂ©nĂ©ration d'une clĂ© privĂ©e/publique. La clĂ© privĂ©e doit ĂȘtre conservĂ©e par l'utilisateur du compte, la clĂ© publique dans la blockchain.
  • Effectuer un transfert de piĂšces, oĂč l'identification de l'utilisateur est faite non pas par le nom, mais par la clĂ© publique.
  • Chiffrer les transactions envoyĂ©es par l'utilisateur au serveur Ă  l'aide de sa clĂ© privĂ©e.

Conclusion

Nous avons implémenté le réseau Citcoin avec les fonctionnalités suivantes : ajouter un compte, obtenir un solde, approvisionner son compte, transférer des piÚces d'un compte à un autre. Alors, quel a été le coût de la construction de la PoC ?

  • Il faut Ă©tudier la blockchain en gĂ©nĂ©ral et Hyperledger Fabric en particulier ;
  • Apprendre Ă  utiliser les clouds d'IBM ou d'Amazon ;
  • Apprendre le langage de programmation JS et un framework web.
  • Si certaines donnĂ©es doivent ĂȘtre stockĂ©es en dehors de la blockchain, dans une base de donnĂ©es distincte, apprenez Ă  vous intĂ©grer, par exemple, avec PostgreSQL ;
  • Et enfin, bien que ce soit le dernier de la liste, il n'est pas moins important — sans connaissances en Linux, on ne fait pas grand-chose dans le monde moderne !)

Bien sûr, ce n'est pas de la science fusée, mais il va falloir fournir un effort !

Sources sur GitHub

J'ai mis les sources sur GitHub. Description succincte du dépÎt :
RĂ©pertoire «serveur» — serveur Node.js
RĂ©pertoire «client» — client Node.js
Répertoire «blockchain» (les valeurs des paramÚtres et les clés, bien sûr, ne fonctionnent pas et sont fournies uniquement à titre d'exemple) :

  • contract — code source du contrat intelligent
  • wallet — clĂ©s de l'utilisateur pour utiliser l'API Hyperledger Fabric.
  • *.cds — versions compilĂ©es des contrats intelligents
  • *.json fichiers — exemples de fichiers de configuration pour utiliser l'API Hyperledger Fabric

Ce n'est que le début !

Source : habr.com

Acheter un hĂ©bergement fiable pour les sites avec protection DDoS, serveurs VPS VDS đŸ”„ Acheter un hĂ©bergement fiable pour les sites avec protection DDoS, serveurs VPS VDS | ProHoster