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 () et les cas d'utilisation qui peuvent ĂȘtre rĂ©alisĂ©s grĂące Ă elles (). 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.

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 :

La version officielle de ce qu'est Hyperledger Fabric peut ĂȘtre consultĂ©e sur , 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 :

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 .
- 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 , pour le dĂ©veloppement et les tests. .
CallFlow

- 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 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 ();
- 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 : ou ici : .
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 :

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 . 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 :

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

Créons des utilisateurs :

Créons un Canal et appelons-le citcoin :

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

Ă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 :

Nous regardons la transaction d'installation du Smart Contract :

Nous consultons les détails de notre Channel :

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) :

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 : . 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 â 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 : . 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 :

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

Nous obtenons la liste de tous les comptes disponibles :

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Ă© :

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

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

Et la liste générale des transactions :

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 . 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
