Déployer et gérer une blockchain Ethereum - La communauté des curieux

TL;DR

Cet article présente une implémentation pratique de la vie associative dans le contexte Covid-19. La technologie sous-jacente utilisée est une blockchain privée de type Ethereum dont les aspects réglementaires et sécuritaires sont discutés fonctionnellement et techniquement. L’objectif est de fournir une alternative digitale sûre pour la gestion des associations et plus spécifiquement des syndicats de copropriété.

Quelques éléments de contexte

Cet article est la suite de Cas d’usage pratique des Smart Contract Ethereum - La communauté des Curieux et vise à montrer comment déployer et gérer une blockchain Ethereum. Le cas d’application est le réseau Ethereum de test que nous allons utiliser pour la communauté des curieux.

Pour revenir au premier volet de cette série et comprendre comment utiliser cette application de blockchain comme un citoyen lambda, il faut choisir le chemin 1 du paragraphe suivant.

Pour revenir au deuxième volet de cette série et comprendre comment les smart contrats fonctionnent et nous aider à gérer la communauté, il faut choisir le chemin 2.

La blockchain dont vous êtes le héros

A partir de maintenant, je vous propose trois chemins de technicité croissante selon ce que vous êtes venu chercher sur cet article.

  1. Je ne suis pas du tout un technicien et je veux faire partie de la copropriété de la communauté des Curieux. Suivez ce chemin.
  2. J’ai des connaissances techniques et je souhaite les approfondir en comprenant comment cette copropriété est construite et les bases technologiques derrière. Suivez ce chemin.
  3. J’ai de bonnes connaissances d’administration système et je veux contribuer au réseau qui est construit. Vous êtes sur le bon chemin, keep going.

Résumé du réseau Ethereum privé

Points importants à noter

Avant d’entrer dans les commandes, deux contraintes structurent tout le déploiement.

  1. N’ayant pas le droit de disposer d’unités de compte à l’étranger, et considérant que la monnaie d’Ethereum, l’éther, en est une, nous n’utiliserons pas la version mondiale publique d’Ethereum mais une version marocaine contrôlée par des marocains. A savoir moi comme initiateur et toute personne qui souhaite rejoindre le réseau par la suite.
  2. La crypto-monnaie “marocaine” naturellement générée par la blockchain étant sujette à caution de la part des autorités réglementaires, cf. le Communiqué de l’AMMC de 2017, nous allons neutraliser sa valeur en générant une quantité très importante au tout début de manière artificielle. Ainsi, ce qui était un asset devient worthless et me semble un bon compromis entre l’adoption de la technologie et les contraintes réglementaires qui visent avant tout à nous protéger des acteurs peu scrupuleux.

Ces points sont également discutés dans les points importants du premier article.

La genèse

Toute blockchain commence par un bloc initial, un seed sur lequel elle va construire ses blocs. Pour une blockchain Ethereum, il prend la forme d’un fichier genesis.json.

{
  "config": {
    "chainId": 985459,
    "homesteadBlock": 0,
    "eip150Block": 0,
    "eip155Block": 0,
    "eip158Block": 0,
    "byzantiumBlock": 0,
    "constantinopleBlock": 0,
    "petersburgBlock": 0,
    "clique": {
      "period": 5,
      "epoch": 30000
    }
  },
  "difficulty": "1",
  "gasLimit": "8000000",
  "extradata": "0x0000000000000000000000000000000000000000000000000000000000000000F72eF0d377515c11056660be5D65A3B4070952540000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  "alloc": {
    "Cd573CAfe4Ded7F71AC094F2b21C0cB42B592E8a": {
      "balance": "1000000000000000000000000000"
    },
    "F72eF0d377515c11056660be5D65A3B407095254": {
      "balance": "1000000000000000000000000000"
    },
    "485d493EB472E10469F14bADa83c33941c018A76": {
      "balance": "1000000000000000000000000000"
    }
  }
}

Les informations importantes à retenir sur ce fichier :

Le deuxième point important est le consensus. Plusieurs types de consensus existent mais deux sont plutôt mainstream :

D’autres types de consensus existent, notamment le PoS, ou proof of stake, qui promet une scalabilité importante du réseau sans algorithme énergivore et qui vient d’être déployé en production dans Ethereum 2.

Notre blockchain devant être la plus privée et contrôlée possible, l’algorithme de Clique sera utilisé comme indiqué dans le fichier genesis.json.

A des fins de test, je me suis octroyé une quantité quasi infinie d’ether à travers alloc, que ce soit pour l’adresse de mon noeud miner 0xCd573CAfe4Ded7F71AC094F2b21C0cB42B592E8a, mon noeud exposé sur internet 0xF72eF0d377515c11056660be5D65A3B407095254 ou ma wallet MetaMask 0x485d493EB472E10469F14bADa83c33941c018A76.

Nous verrons par la suite comment ajouter d’autres miners/signers.

L’instanciation de mon noeud

Le fichier genesis.json en poche, nous pouvons instancier notre miner avec les commandes suivantes.

Initialisation du répertoire de données :

/usr/bin/geth init \
  --datadir /home/ethereum/node/data \
  /home/ethereum/node/genesis.json

Noeud exposé sur internet, appelé node :

/usr/bin/geth \
  --datadir /home/ethereum/node/data \
  --nodiscover \
  --networkid 985459 \
  --http \
  --http.addr 0.0.0.0 \
  --http.corsdomain "curieux.ma" \
  --http.api web3,personal,eth,net \
  --port 30303 \
  --syncmode full \
  --http.vhosts '*'

Noeud miner/signer, appelé distributor :

/usr/bin/geth \
  --datadir /home/ethereum/distributor/data \
  --nodiscover \
  --networkid 985459 \
  --port 30305 \
  --unlock 0xF72eF0d377515c11056660be5D65A3B407095254 \
  --password /home/ethereum/distributor/password.txt \
  --mine \
  --syncmode full \
  --miner.gasprice 0 \
  --txpool.pricelimit 0

Le premier noeud expose les API HTTP pour MetaMask, expose le port 30303 pour d’éventuels noeuds qui aimeraient s’ajouter au réseau et n’autorise de requêtes CORS que pour le domaine curieux.ma.

Il existe un autre nœud que j’appelle le distributor, non exposé sur internet. Ce noeud me sert à valider les transactions et à servir une petite application Node qui sert de manière automatique le 1 ETH à travers le bouton Recevoir de l’ether.

Une fois ces commandes exécutées, le premier noeud qui est exposé est prêt à travailler et se synchronisera avec tout autre noeud avec lequel il serait connecté.

Déployer votre propre noeud

Je décris les différentes étapes dans le fichier instructions_ethnode.txt. Elles sont un peu pêle-mêle, donc voici les macro-étapes pour rejoindre le noeud existant.

1. Sysadmin classique

Je passe les étapes classiques de configuration d’un VPS. Je pars en général sur la dernière distribution Ubuntu et je déroule le grand classique first 5 minutes of essentials and security.

Checklist minimale :

2. Préparation Ethereum

Une fois tout cela fait, il faut ouvrir le port 30303 de votre machine pour préparer le terrain à la communication des nœuds Ethereum.

On installe Geth :

apt-get install software-properties-common
add-apt-repository -y ppa:ethereum/ethereum
apt-get update
apt-get install ethereum

Puis on configure une wallet qui servira de base au miner :

/usr/bin/geth account new --datadir /home/ethereum/node/data

Cette adresse vous servira plus tard pour miner des blocs.

3. Instanciation du noeud Ethereum

Lorsque les prérequis sont là, on récupère le fichier genesis.json qui sera le seed du noeud.

wget https://raw.githubusercontent.com/AshtonIzmev/ethereum-association/master/eth/genesis.json

Puis on initialise le noeud avant de le lancer.

/usr/bin/geth init \
  --datadir /home/ethereum/node/data \
  /home/ethereum/node/genesis.json

/usr/bin/geth \
  --nodiscover \
  --datadir /home/ethereum/node/data \
  --networkid 985459 \
  --syncmode full

Rien de plus simple, le nœud est fonctionnel mais sans être connecté au réseau. Pour réaliser cette opération, il faut récupérer l’enode d’un nœud exposé et l’utiliser.

Par exemple, mon noeud exposé a comme enode enode://[email protected]:55132, récupérée sur ma machine avec la commande :

geth attach /home/ethereum/node/data/geth.ipc --exec admin.nodeInfo.enode

Il faut donc exécuter sur votre noeud :

ENODE="enode://e3ebe5588575899fc25c2597ed5c3b7dfe05f26dd6a82f1f5b398d89830b4957ee30481beff7521c5da9794b8bbf5792c9c7be97ab11d7aff37804bdd0ba7a8d@209.250.236.210:30303"

geth attach /home/ethereum/node/data/geth.ipc \
  --exec "admin.addPeer('${ENODE}')"

geth attach /home/ethereum/node/data/geth.ipc \
  --exec "admin.peers"

4. Rejoindre la clique

Vous avez à présent un nœud parfaitement connecté et synchronisé par la blockchain initiale. Il peut interagir, envoyer des transactions et être le relais avec une Dapp par exemple à travers les API HTTP-RPC.

Par contre, il n’est pas encore autorisé à signer des transactions car notre réseau est privé.

Vous devez relancer votre noeud avec une commande spéciale unlock et un fichier PASSWORDFILE qui contient la passphrase de votre wallet.

/usr/bin/geth \
  --nodiscover \
  --datadir /home/ethereum/node/data \
  --networkid 985459 \
  --syncmode full \
  --unlock VOTREADRESSE \
  --password PASSWORDFILE

Le champ VOTREADRESSE doit être rempli avec l’adresse publique que vous avez obtenue en créant une nouvelle wallet.

La clique permet d’autoriser un nouveau miner à travers un protocole de vote majoritaire. A ce stade-là, vous devez envoyer l’adresse que vous utilisez à toute personne existante dans le réseau en tant que miner/signer. Et éventuellement les convaincre de votre sérieux :)

Pour ma part, je dois ensuite voter pour vous sur mes propres noeuds :

geth attach /home/ethereum/node/data/geth.ipc \
  --exec 'clique.propose("VOTREADRESSE", true)'

Si suffisamment de personnes votent pour vous, vous êtes admis dans la clique et autorisé à signer des transactions.

Votre nœud ayant été éteint pour ajouter unlock et password, il faut relancer le peer add et lancer un miner également.

ENODE="enode://e3ebe5588575899fc25c2597ed5c3b7dfe05f26dd6a82f1f5b398d89830b4957ee30481beff7521c5da9794b8bbf5792c9c7be97ab11d7aff37804bdd0ba7a8d@209.250.236.210:30303"

geth attach /home/ethereum/node/data/geth.ipc \
  --exec "admin.addPeer('${ENODE}')"

geth attach /home/ethereum/node/data/geth.ipc \
  --exec "admin.peers"

geth attach /home/ethereum/node/data/geth.ipc \
  --exec "miner.start()"

Nos nœuds sont désormais synchronisés et interdépendants. Si l’un d’entre nous devait disparaître, le réseau serait alors arrêté car un des signataires serait absent.

Devenir miner traduit une relation de confiance dans le réseau et ne se fait pas à la légère. C’est la différence principale entre une blockchain privée et une blockchain publique où seul le travail algorithmique et la dépense énergétique comptent.

Si vous désirez quitter le réseau, une majorité de 51% des autres signers doivent voter votre exclusion afin de rétablir le bon fonctionnement du réseau :

geth attach /home/ethereum/node/data/geth.ipc \
  --exec 'clique.propose("VOTREADRESSE", false)'

geth attach /home/ethereum/node/data/geth.ipc \
  --exec 'clique.propose("VOTREADRESSE", false)'

Si vous pensez avoir assez de stabilité sur quelques mois, devenez un signer. Sinon, soyez simplement un relai du réseau sans être signer de transaction.

Quelques bonnes pratiques

Je lance mes noeuds dans des services systemd. Voici un exemple au cas où ce serait utile :

[Unit]
Description=Ethereum private network node
After=network.target

[Service]
User=ethereum
Group=ethereum
Environment=HOME=/home/ethereum
Type=simple
ExecStart=/usr/bin/geth \
  --datadir /home/ethereum/node/data \
  --nodiscover \
  --networkid 985459 \
  --http \
  --http.addr 0.0.0.0 \
  --http.corsdomain "curieux.ma" \
  --http.api web3,personal,eth,net \
  --port 30303 \
  --syncmode full \
  --miner.gasprice 0 \
  --txpool.pricelimit 0 \
  --http.vhosts '*'
KillMode=process
KillSignal=SIGINT
TimeoutStopSec=90
Restart=on-failure
RestartSec=10s

[Install]
WantedBy=multi-user.target

Pour les passphrases et les mots de passe en général, j’aime bien utiliser pwgen.

pwgen -s -y 30

Si 5 dollars par mois n’est pas beaucoup pour vous et que vous voulez jouer avec le réseau Ethereum, je vous suggère d’aller chercher un VPS sur vultr.com localisé en Europe, pour un ping faible, sur une Ubuntu 20.04 LTS. Ces instances se lancent en quelques minutes et sont facturées à l’heure. Je me retrouve parfois à payer moins de quelques centimes pour des expérimentations de quelques heures.

Conclusion

Cet article clôt la série des deux autres articles avec une plongée dans le déploiement d’un nœud Ethereum. Comme vous pouvez le constater, les étapes ne sont pas nombreuses pour devenir un miner mais il faut bien comprendre les subtilités des algorithmes de consensus et de la ligne de commande geth.

J’ai bon espoir que plusieurs lecteurs trouvent ce tutoriel utile et se connectent à mon nœud exposé afin de simuler un vrai réseau privé marocain. Pour les plus courageux, je vous attends.

Liens vers les photos

Photo by Isaac Davis on Unsplash