Il y a un peu plus d’un an à présent, nous avons développé une solution d’horodatage basée sur une blockchain. Elle permet de prouver l’antériorité d’un contenu (une idée ou une création par exemple) via l’utilisation d’une blockchain publique Ethereum directement depuis son navigateur. Donc sans organe central de contrôle. Il s’agit d’un cas d’usage simple mais parfaitement applicable aux besoins métiers des applications de nos clients : sceller un contenu et ses métadonnées de manière sûre et pérenne. Le code source est publié sous la licence Apache 2.

Pour faciliter la lecture, nous vous proposons une série de cinq articles qui présentent trois points de vue complémentaires de l’outil :

  1. Point de vue conceptuel : 🎨 Comprendre les notions de base d’une blockchain publique
  2. Point de vue utilisateur : 🕺 Interagir avec l’application décentralisée
  3. Point de vue développeur : 🏭 Configurer son environnement de développement
  4. Point de vue développeur : 🤝 Comprendre le développement du smart contract
  5. Point de vue développeur : 💻 Comprendre le développement du client

Ce cinquième et dernier article est l’occasion d’aborder le développement du client web qui interagit avec le smart contract développé et déployé précédemment.

Les sources sont disponibles dans le sous-projet front. Il a principalement été écrit avec VueJS pour la présentation et web3 pour les appels à la blockchain.

Nous nous intéressons ici uniquement aux interactions avec la blockchain. Le code est simplifié dans ce qui suit pour se focaliser sur ce qui est essentiel.

# Module blockchain (web3 / jssha)

Ce qui concerne purement la blockchain a été placé dans un module dédié placé dans front/src/lib/BlckchnAntProver.js.

web3.js est un ensemble de librairies qui permet d’interagir avec un nœud Ethereum local ou distant via HTTP, IPC ou WebSocket. On l’importe :

Nous importons également les métadonnées produites lors de la compilation du smart contract AntProver.sol (cf. article précédent) afin de référencer le contrat ABI et de récupérer les adresses du smart contract déployé dans différents réseaux :

L’identifiant du réseau choisi par l’utilisateur dans Metamask est récupéré via web3 :

L’initialisation est réalisée par un appel à la fonction init qui prend deux paramètres :

  • allowGanache : pour permettre un fallback Ganache. Par exemple on l’interdit en production avec le test process.env.NODE_ENV !== 'production'
  • _hashAddedCallback : un callback optionnel pour rĂ©agir lorsqu’un Ă©vĂ©nement arrive

Pour l’initialisation, on crée une instance de Web3 en utilisant par ordre de préférence :

  1. window.ethereum injecté par Metamask (dernière API)
  2. window.web3.currentProvider également injecté par Metamask dans ses versions plus anciennes
  3. Web3.providers.HttpProvider : un provider HTTP pour se connecter à Ganache en fallback si on l’a permis

Les commentaires indiquent les étapes d’initialisation :

L’initialisation (ou la rĂ©initialisation) de l’accès au smart contract est rĂ©alisĂ©e dans la fonction initContract. Elle consiste essentiellement Ă  crĂ©er une instance de web3.eth.Contract et relayer l’évĂ©nement HashAdded via le callback de manière Ă  faire rĂ©agir l’application (pour rappel, les Ă©vĂ©nements entrants sont Ă©coutĂ©s afin de gĂ©nĂ©rer les certificats pdf au besoin) :

Pour le référencement d’un contenu, on utilise directement la fonction importée des métadonnées du smart contract en traitant la réponse avec un callback après s’être assuré d’avoir bien le compte utilisateur (ici, on prend le premier) :

Les fonctions de lecture de données répondent au même principe. Par exemple, la recherche d’un contenu prend un hash en entrée et appelle un callback pour traiter le retour :

L’écriture de quelques fonctions de manipulation de hash a Ă©tĂ© nĂ©cessaire  : readUploadedFileAsText, calculateHashFromBytes et calculateHashFromFile. Ces dernières ne sont pas dĂ©taillĂ©es dans cet article. Je vous invite Ă  consulter la librairie jssha utilisĂ©e en background.

Pour finir sur ce module, les fonctions sont exportées afin d’être utilisées par l’application. L’ensemble des fonctions est le suivant :

Ainsi ce module permet de traiter l’aspect purement lié à la blockchain : initialiser la connexion au smart contract déployé dans la blockchain sélectionnée par l’utilisateur dans Metamask, s’assurer que le compte de l’utilisateur est sélectionné avant de tenter une écriture dans la blockchain (ou provoquer sa sélection), se charger des appel à la blockchain et mettre en place l’écoute des événements afin de les relayer.

La suite est moins détaillée dans la mesure où il s’agit d’utiliser les fonctions de ce module.

# Initialisation

L’application est constituée de bloc fonctionnels et techniques. Chacun des blocs est un composant Vue.js créé dans l’application App.vue. On retrouve logiquement l’inclusion des balises dans le template de l’application :

Ainsi que l’initialisation évoquée plus haut réalisée lorsque l’application Vue.js est montée et que la page est chargée.

On initialise le lien avec la blockchain et on stocke les informations dans le store Vuex qui permet la gestion d’états dans l’application. Ce dernier est utilisé à la fois pour les événements entrants et pour les informations techniques sur la blockchain choisie :

# Composant d’écriture

Le bloc J’ancre un contenu est implĂ©mentĂ© par le composant Upload.vue.

Le module blockchain décrit précédemment permet d’interagir avec la blockchain sans connaître les détails sous-jacents. On utilise la fonction de calcul du hash lorsqu’un fichier est chargé :

Ainsi que la fonction d’envoi d’un hash lorsque le formulaire est soumis :

# Composant de lecture

La recherche du référencement d’un fichier du bloc Je vérifie un contenu est réalisée dans le composant Check.vue.

Là aussi, le composant est agnostique vis à vis de la blockchain. On calcul le hash lorsqu’un fichier est chargé :

Et on effectue la recherche lorsque le formulaire est soumis :

# Smart contract et ABI

Le contrat ABI (Application Binary Interface) définit la manière d’interagir avec un smart contract. Il s’agit d’une interface entre le smart contract et un client.

Nous avons vu au début de cet article que nous avons importé le contrat ABI du smart contract que nous avons développé initialement puisque nous le versionnons dans les sources :

Nous aurions également pu le récupérer à partir de la blockchain. Par exemple, le smart contract est déployé dans la blockchain Goerli à l’adresse 0xE9D0E1857CcaAE1E608E6e9b5fdFa1CD6D267733 et son code source est vérifié. Le contrat ABI est disponible au format json à cette adresse.

 

# Synthèse de l’article

Cet article illustre le développement d’un client web Ethereum.

Il faut retenir que l’extension Metamask expose son API en injectant l’objet ethereum dans la page que nous fournissons lors de l’initialisation de l’application avec web3, librairie de communication avec les blockchains Ethereum.

Pour simplifier l’interaction avec un smart contract déployé dans une blockchain Ethereum, il est conseillé de commencer par écrire une API dédiée dans un module afin de traiter l’initialisation, la sélection de compte, les appels concrets et relayer les événements.

Dans le reste de l’application, il s’agit ainsi d’utiliser cette API qui rend la consommation agnostique et facilite l’écriture du code, sa compréhension et sa maintenance.

Nous pouvons exploiter le contrat ABI généré lors de la compilation du smart contract ou le récupérer lorsque ce dernier est déployé. Il fournit déjà un premier niveau d’API avec les objets métiers du smart contract.

# Synthèse de la série d’articles

Cette série d’articles touche à sa fin.

Le cas d’usage se prête bien à l’exercice pédagogique : faire de la preuve d’antériorité à partir d’un smart contract déployé dans une blockchain, directement depuis son navigateur.

Nous avons commencé avec un point de vue conceptuel dans le premier article en expliquant ce qu’apporte la blockchain dans le cas d’usage : notamment la simplicité administrative, le coût d’infrastructure quasi nul et la résilience. Nous avons également synthétisé le fonctionnement d’une blockchain Ethereum : la sécurité assurée par la crypto et les consensus, l’organisation du stockage en chaîne de blocs distribuée, le coût des transactions et les jetons de monnaie et ce qu’apportent les smarts contracts. La suite du premier article a été consacrée à la manière d’interagir avec une blockchain depuis son navigateur : l’extension Metamask et son portefeuille, comment l’alimenter pour réaliser des micro-paiements. Puis nous avons montré en quoi une blockchain publique est transparente : les opérations sont visibles ainsi que les pseudonymes de leurs auteurs. Les transactions d’une blockchain ne sont donc pas forcément anonymes.

Dans un second temps, nous avons exposé un point de vue utilisateur dans le deuxième article avec la démonstration de l’ergonomie de l’application : la configuration initiale de Metamask, puis l’utilisation de l’outil qui reste classique hormis lors d’une opération d’écriture. En effet, le consentement de l’utilisateur est demandé dans la mesure où ce dernier supporte le coût de la transaction. En revanche, aucun frais n’est appliqué pour la consultation.

La suite est consacrée au point de vue du développeur en trois temps : la configuration de son environnement de développement, le développement du smart contract et le développement du client web.

Les sources du projet sont accessibles dans la mesure où elles sont publiées sous la licence Apache 2. Pour les développements, il est possible d’instancier une blockchain de développements avec Ganache. C’est cette blockchain qui est exploitée dans l’article 3 qui décrit comment compiler et le déployer le smart contract dans celle-ci et comment servir le client web pour commencer à valider son environnement.

Le développement du smart contract est expliqué dans l’article 4 : le langage solidity, le squelette, les structures et les variables, les fonctions d’écriture et de lecture, les prérequis ainsi que la production d’événements. Pour compléter l’article 3, nous précisons la manière de gérer les migrations grâce à truffle et le déploiement vers une blockchain publique officielle à travers Infura.

Enfin, le dernier article expose une manière de produire le client web : l’écriture d’un module javascript dédié aux interactions avec la blockchain via Metamask à travers web3 et l’utilisation de cette API dans le reste de l’application qui constitue un projet classique dans la manière de l’aborder, l’ergonomie liée à la configuration de son compte et le consentement mis à part.

Je vous remercie d’avoir pris le temps de nous lire et vous invite Ă  nous laisser un commentaire Ă  la suite de cet article si vous avez des questions ou des remarques ou simplement pour nous indiquer si vous ĂŞtes arrivĂ©s jusque-lĂ  sain et sauf ! ⬎