XinCTO/votre premier lab blockchain

Ecrit le Sat, 11 November 2017 17:01:43 +0000
1892 mots 9 minutes

votre premier lab blockchain

La blockchain tout le monde en parle, c’est parfois complexe à comprendre et un petit lab pour démistifier pourrait être intéressant, non ?

Je vous propose ici de faire quelques tours de roue avec multichain qui nous propose une approche opensource (sous licence GPLv3) assez complète et aboutie d’une blockchain. De nombreux concepts sont embarqués, plus que nécessaire pour cette petite balade, mais cela vous donnera peut-être des idées pour la suite.

Si vous ne savez pas encore ce qu’est une blockchain, vous trouverez des articles sur la toile à n’en pas douter, mais pour commencer, celui-ci sur Blockchain France est assez simple et ludique.

De façon à vous simplifier la vie avec l’outil, je vous propose d’utiliser des containers docker que je vous ais préparé avec amour, incluant tout ce qui est nécessaire pour ce lab, rien de bien complexe, c’est juste pour gagner du temps.

Compter 30 à 60 minutes pour ce lab.

Installation

Creation du container

Sur votre Linux préféré, récupérer le package que je vous mets à disposition sur git :

1git clone https://github.com/achauvinhameau/multichain-lab.git
2cd multichain-lab

puis, créer l’image docker :

1docker build -t multichain-lab .

La construction va prendre quelques minutes, disons moins de 5 si vous disposez d’un peu de CPU et de bande passante internet pour les mises à jour.

Le container ainsi construit fait un peu moins de 500 MB et est basé sur CentOS. Il embarque de quoi faire aussi bien le premier noeud qui propose une interface web pour regarder simplement comment tout cela fonctionne, que l’outil multichain. Le premier noeud démarré créera également la blockchain, car il faut bien démarrer, les noeuds suivants s’y connecteront et pourront participer à la chaine de confiance, faire des transactions et miner des blocks pour les rendre valides.

Lancement du premier noeud

Pour le premier noeud, pas de précaution particulière, on le limite juste en utilisation de mémoire à 64MB et on expose le port du serveur web sur le port 80, à modifier en fonction de l’environnement de votre serveur docker.

1docker run -d --name node1 --rm -p 80:80 -m 64m multichain-lab

Une fois démarré, vous pouvez (devez même) accéder à l’interface web proposée et choisir la chaine par défaut construite, elle se nomme Default. Faites un petit tour du propriétaire histoire de voir un peu ce qui est présenté.

Vous remarquerez sur la page des noeuds que ce premier est accessible par une adresse interne à multichain, récupérable également via le log du container (docker logs node1), pour moi c’est le chain1@172.17.0.2:2510. Une première blockchain est créée, elle se nomme chain1.

Si vous souhaitez voir comment ce noeud se comporte de l’intérieur, vous pouvez utiliser la commande multichain-cli directement dans le container, je vous mets quelques lignes du json résultant, faites l’exercice sur votre node1 pour la version complète et adaptée à votre contexte :

 1$ docker exec -it node1 bash
 2# multichain-cli chain1 getinfo
 3{
 4    "version" : "1.0.2",
 5    "nodeversion" : 10002901,
 6    "protocolversion" : 10009,
 7    "chainname" : "chain1",
 8    "description" : "MultiChain chain1",
 9    "protocol" : "multichain",
10    "port" : 2510,
11    "setupblocks" : 60,
12    "nodeaddress" : "chain1@172.17.0.2:2510",
13    "balance" : 0.00000000,
14    "blocks" : 59,
15    "difficulty" : 0.00000006,
16    "errors" : ""
17}

On peut constater ici, également dans l’interface web, que la chaine se remplit progressivement de blocs, jusqu’à en compter 60, ce qui correspond à l’initialisation de la chaine (paramètre setup-first-blocks) et certaines restrictions notamment au niveau de la capacité des autres noeuds à faire du minage. Ici, il n’y a qu’un seul noeud, pas de problème de conflit potentiel.

Le principe de chainage des blocks est explorable via les champs hash dans chaque bloc, je ne vous mets que les 6 derniers caractères du hash pour simplifier la lecture. Noter que le premier bloc ne possède pas de bloc précédent :

 1# multichain-cli chain1 getblock 0 | fgrep hash
 2    "hash" : "35310e",
 3    "nextblockhash" : "683d23"
 4
 5# multichain-cli chain1 getblock 1 | fgrep hash
 6    "hash" : "683d23",
 7    "previousblockhash" : "35310e",
 8    "nextblockhash" : "ec21d2"
 9
10# multichain-cli chain1 getblock 2 | fgrep hash
11    "hash" : "ec21d2",
12    "previousblockhash" : "683d23",
13    "nextblockhash" : "b51783"

Lancement des autres noeuds

Nous allons démarrer quelques noeuds qui vont agrandir notre chaine de participants à la blockchain, pour cela il est nécessaire qu’ont leur attribue des droits, le plus simples est de le faire pour chacun, au démarrage, via l’interface web.

Pour simplifier les opérations à suivre, je vous conseille d’attendre d’avoir les 60 transactions dans la chaine, sur l’interface web vous devez avoir la valeur du champ Blocks à 59. Ceci devrait prendre une quinzaine de minutes en gros (1 block pour 20 secondes).

Pour chaque nouveau noeud :

  • aller dans l’onglet Permissions et cocher les droits Connect, Send, Receive et Mine
  • lancer le container en changeant le nom de celui-ci et en ajustant la variable MC_FIRST avec l’adresse du premier noeud de la chaine si nécessaire
1docker run -d --name node2 --rm -m 48m -e MC_FIRST=chain1@172.17.0.2:2510 multichain-lab
2docker logs node2
  • ajouter ses droits en copiant son adresse apparaissant dans le log dans le champ For address et en validant

Sur la page Node vous devez retrouver chaque noeud avec ses droits. Vous pouvez en lancer plusieurs (disons 4 en tout) en fonction de vos capacités de serveur, chaque container consomme environ 32MB

Analyse d’une transaction

Si vous avez attendu d’avoir les 60 premiers blocs créés avant de démarrer les noeuds suivants, nous allons nous concentrer sur le bloc 60 et son contenu :

1# multichain-cli chain1 getblock 60
2{
3    "tx" : [
4        "5b190dee33918d8c15433c81d81fc755a564defd7d2c215ccec2c92f0461dcf9",
5        "a3c052339da36c302d18e0ba3b17cf28f6385d5247e5106baece6f98e8ebde6a"
6    ]
7}

Il est composé de 2 transactions (tx), la seconde (dans mon cas) contient la modification de permission que nous avons fait lors de l’ajout du node2 dans la liste des serveurs. Pour explorer la transaction, nous devons utiliser son adresse dans la commande suivante, le 1 à la fin permet d’avoir le contenu complet (un extrait ici avec quelques informations) :

 1# multichain-cli chain1 getrawtransaction a3c052339da36c302d18e0ba3b17cf28f6385d5247e5106baece6f98e8ebde6a 1
 2{
 3    "txid" : "a3c052339da36c302d18e0ba3b17cf28f6385d5247e5106baece6f98e8ebde6a",
 4    "vout" : [
 5        {
 6            "scriptPubKey" : {
 7                "asm" : "OP_DUP OP_HASH160 6469...f4 OP_EQUALVERIFY OP_CHECKSIG 7370...5a OP_DROP",
 8                "addresses" : [
 9                    "1Ea8bBfVMD4TAH2tQa1ijHy28HS6zi4SwEWFKR"
10                ]
11            },
12            "permissions" : [
13                {
14                    "for" : null,
15                    "connect" : true,
16                    "send" : true,
17                    "receive" : true,
18                    "create" : false,
19                    "issue" : false,
20                    "mine" : false,
21                    "admin" : false,
22                    "activate" : false,
23                    "startblock" : 0,
24                    "endblock" : 4294967295,
25                    "timestamp" : 1510419831
26                }
27            ],
28            "items" : [
29            ]
30        },
31        {
32            "scriptPubKey" : {
33                "asm" : "OP_DUP OP_HASH160 f375...42 OP_EQUALVERIFY OP_CHECKSIG",
34                "hex" : "76a914f37500d793988858c7a45b61c57d2a81c838c54288ac",
35                "reqSigs" : 1,
36                "type" : "pubkeyhash",
37                "addresses" : [
38                    "1ZuTKqatJMZCccivXFBnPnakKwV1rzzD3dEp5B"
39                ]
40            },
41    ],
42    "time" : 1510419852,
43    "blocktime" : 1510419852
44}

Sur cet extrait on retrouve sur le premier block vout l’ajout des permissions à destination du noeud ajouté en premier (dans mon cas), dans la partie asm le langage utilisé avec les arguments.

On peut constater que l’octroi des droits est également transporté dans la chaine, donc tout le monde peut les vérifier à tout moment.

Dans mon cas, le bloc 69 contient les permmissions pour le troisième noeud ajouté celon le même principe.

Transactions

Bon, c’est bien beau tout cela, mais peut-on se servir de cette blockchain pour faire quelque chose avec un peu plus de valeur ? Oui, bien sûr, on y va.

Créer un produit

Dans multichain, on effectue des transactions sur des produits (assets). Ceci est un peu différent de bitcoin qui ne permet que de n’échanger qu’un seul type de produit, en l’occurrence une monnaie. Alors créons quelques produits que nous pourrons échanger ensuite, ils doivent à minima être nommés, disposer d’une unité d’échange et on doit également en inserer une quantité multiple de cette unité dans la chaine et attribué à un noeud (wallet). Par exemple, ajoutons 100 choux échangeables à l’unité et 300 carottes échangeables par 5. Ceci est à faire à partir de la page Issue Assets de l’interface web. Vous remarquerez que l’on peut enrichir nos produits d’un fichier et de champs au format clé/valeur.

Sur l’interface web il est nécessaire de saisir une adresse de destination qui se verra crédité du stock ainsi créé. La liste étant triée, il sera nécessaire de choisir l’adresse locale, sinon, le stock sera attribué à un autre noeud (pas gênant pour cet exercice).

Sur le noeud crédité, vous pouvez visionner le portefeuille avec la commande getaddressbalances :

 1# multichain-cli chain1 getaddressbalances 1Ea8b...KR
 2[
 3    {
 4        "name" : "choux",
 5        "assetref" : "92-543-5905",
 6        "qty" : 100.00000000
 7    },
 8    {
 9        "name" : "carotte",
10        "assetref" : "92-265-11383",
11        "qty" : 300.00000000
12    }
13]

Créer une transaction

Sur le noeud qui détient du stock d’un produit, à partir de l’interface web utilisez le menu Send, spécifier l’adresse de destination dans la liste, le produit et la quantité, c’est parti ! La balance est automatiquement ajustée et une fois la transaction validée par un block miné, le noeud destination sera crédité de la quantité de produit envoyé.

A partir de la commande en ligne sur le noeud propriétaire des assets utiliser la commande sendasset.

Si vous êtes curieux, vous trouverez la transaction dans la blockchain avec les commandes getblock et getrawtransaction, concentrez-vous sur les blocs avec plusieurs transactions.

Lister les transactions

multichain propose un principe d’abonnement à des files de message, chaque produit disposant de sa propre file. Il est donc possible de connaitre toutes les transactions sur un asset de la chaine. Par défaut, les noeuds ne sont pas abonnés au files de messages des produits. En revanche il est possible de s’y abonner et d’explorer les transactions :

 1# multichain-cli chain1 subscribe carotte
 2# multichain-cli chain1 listassettransactions carotte
 3    {
 4        "addresses" : {
 5            "1ZuTKqatJMZCccivXFBnPnakKwV1rzzD3dEp5B" : 1.00000000,
 6            "1Ea8bBfVMD4TAH2tQa1ijHy28HS6zi4SwEWFKR" : -1.00000000
 7        },
 8        "confirmations" : 64,
 9        "blockhash" : "008a6b863b006dd724785839ac20ccd431462a71776cac94533cbe257562619e",
10        "blocktime" : 1510422053,
11        "txid" : "55686ecc9b7c4fabcc4cc353032bf44546f3ac61f8c90a1ec3778a404f34e44c",
12        "valid" : true,
13        "time" : 1510422035,
14        "timereceived" : 1510422035
15    },

Miners

Dans notre lab nous avons donné la permission de minage à chaque noeud, vous pouvez vérifier qu’effectivement la charge a bien été partagée au sein de votre réseau de noeud sur le sujet du minage, à l’exception des 60 premiers blocs comme vu précédemment :

1# multichain-cli chain1 listblocks 60-184 | fgrep miner | sort | uniq -c
2     25         "miner" : "1Ea8bBfVMD4TAH2tQa1ijHy28HS6zi4SwEWFKR",
3     33         "miner" : "1HMcy7iM5kf2d9yGdVAZcJqcUFs551P59oDx5o",
4     26         "miner" : "1JKMPW736tBDkfQFW2MpADQq4vPbipyVp7csYK",
5     41         "miner" : "1ZuTKqatJMZCccivXFBnPnakKwV1rzzD3dEp5B",

Conclusion

Voilà en quelques minutes un petit tour d’horizon de l’usage d’une blockchain. Cela lève probablement un peu de doute si vous en aviez et surtout doit vous donner des idées de usecase.

A noter que la solution multichain est ouverte et bien que tous les exemples présentés ici ont utilisé les commandes en ligne ou l’interface web, toutes les fonctions sont accessibles via des API REST ; la syntaxe vous est donné en retour de chaque commande sur la première ligne.

Si vous voulez aller plus loin, il y a beaucoup de documentation disponible sur le site multichain directement, des tutos, des vidéos et une communauté assez large.


Photo from Kaley Dykstra

Voir aussi