Ethereum et Angular — Part 1
Créer une Application Décentralisée
Installation
Une application décentralisée, ou Dapp, consiste en une application client qui interagit avec la blockchain Ethereum.
Créons une application Angular avec angular-cli :
ng new ng-eth
Une fois toutes les dépendances installées nous allons ajouter la librairie JavaScript permettant d’interagir avec la blockchain Ethereum : Web3.js
. A noter que Web3 est en développement intense et la version 1.0.0 est toujours en beta.
npm install web3@1.0.0-beta.30
Commençons par créer un nouveau module à l’application : ethereum
. Ce module a pour but de rassembler tous les components et services permettant d’interagir avec la blockchain Ethereum.
ng g module ethereum
Le module sera composé de plusieurs components souvent utilisés sur les applications décentralisées ainsi qu’un ensemble de services qui manipuleront les données de la blockchain.
Instancier Web3
La librairie Web3 nous fournit une classe que nous devons instancier et qui sera réutilisée dans plusieurs services de l’application. La meilleure manière de réutiliser la même instance d’une classe dans plusieurs class Angular est de créer un InjectionToken
avec useFactory
:
Dans le dossier Ethereum
nouvellement créé par angular-cli ajoutons un nouveau fichier : tokens.ts
Ethereum
— ethereum.module.ts
— tokens.ts
Créons un token WEB3 :
Ce code nous permet de définir un Token que nous pourrons injecter dans les classes Angular. Pour cela, ajoutons un provider à la liste des providers de ethereum.module.ts
.
Tout d’abord importez Web3. Le fichier de définitions des types Typescript n’étant pas encore à jour je vous invite à utiliser require
.
const Web3 = require(‘web3’) ;
Puis ajoutez WEB3 comme provider du module :
providers: [{
provide: WEB3,
useFactory: () => new Web3(Web3.givenProvider || "ws://localhost:8546");
}]
Nous ajoutons un nouveau provider au module ethereum qui permettra d’injecter web3 dans tout le module, et autres modules qui importeront EthereumModule
. Remarquons ici que nous utilisons useFactory
pour créer une unique instance de notre classe Web3 à travers toute l’application.
Concentrons-nous un peu sur le contenu de Web3. Le code new Web3(Web3.givenProvider || “ws://localhost:8546”);
vient directement de la documentation de Web3. Pour interagir avec la blockchain Ethereum, une application décentralisée doit tout d’abord se connecter à un nœud du réseau. Pour cela il y a deux options :
- Soit votre utilisateur ouvre votre application dans un environnement qui est déjà connecté à un nœud (MetaMask, Mist, Toshi, …) dans ce cas nous utilisons le
Web3.givenProvider
. - Soit votre utilisateur a un nœud tournant sur sa machine et dans ce cas il se connecte à ce nœud. Remarquons que le protocole recommandé par web3 pour se connecter à un nœud est le WebSocket :
ws://localhost :8546
.
Notons qu’il est également possible de gérer soi-même son propre provider avec le provider-engine de metamask, mais cela fera l’objet d’un autre article.
Insistons sur la nécessité d’utiliser le Web3.givenProvider
s’il est disponible car ces environnements hook certaines fonctions de web3 avec une interface graphique particulière (MetaMask, Mist, …). L’utilisateur s’attend à voir ces mêmes interfaces apparaitre, notamment lorsqu’il réalise une transaction ou signe un message. S’il ne retrouve pas ces interfaces il ne fera pas confiance à votre DAPP.
Notre module devrait ressembler à cela :
Interagir avec la blockchain
Nous avons donc instancié la classe Web3 avec l’environnement le plus adapté à chaque utilisateur, il est temps de l’utiliser dans un service pour interagir avec la blockchain.
Nous avons donc instancié la classe Web3 avec l’environnement le plus adapté à chaque utilisateur, il est temps de l’utiliser dans un service pour interagir avec la blockchain.
Créons un service dans notre module ethereum : eth.
ng g service ethereum/eth
Tout d’abord injectez l’instance de Web3 que nous avons codé préalablement :
constructor(@Inject(WEB3) private web3: Web3) { }
Nous utilisons ici le decorator @Inject pour récupérer la valeur du Token ajouté à la liste des providers du module.
Ce service a pour but d’encapsuler les fonctions de Web3 du module Eth. Web3 est construit pour être asynchrone et chaque fonction asynchrone retourne une Promise. Angular fait plutôt un usage intensif des Observables. Encapsulons certaines de ces Promises dans des Observables pour simplifier l’intégration dans le reste de l’application.
Commençons simplement par récupérer la liste des comptes disponibles sur le nœud :
Pour l’instant cette fonction ne fait qu’encapsuler la fonction web3 dans un observable. Créons à présent une fonction permettant d’accéder au compte sélectionné, ou au premier compte, si aucun compte n’est sélectionné.
Cette fonction utilise pleinement la puissance des observables. Découpons là en morceaux :
if (this.web3.eth.defaultAccount) {
return of(this.web3.eth.defaultAccount);
}
Nous vérifions d’abord s’il y a déjà un compte sélectionné sur notre instance de web3. Si oui, nous renvoyons un observable avec l’adresse de ce compte. L’utilisation d’un observable ici permet à la fonction de se comporter toujours de la même manière quelque-soit le résultat de la condition.
else {
...
}
Si aucun compte n’est sélectionné nous utilisons la précédente fonction pour récupérer la liste de comptes disponibles. Cette fonction retourne un tableau d’adresse ethereum encapsulé dans un observable. Nous vérifions que le tableau n’est pas vide, sinon nous renvoyons une erreur qui sera ensuite récupérée dans le catchError
.
Si le tableau n’est pas vide, nous récupérons la première adresse et nous en profitons pour définir cette adresse comme celle du compte sélectionné dans l’instance de web3. Cela nous évitera de rechercher la liste des comptes disponibles par la suite.
Rappelons que tous ces opérateurs doivent être importés dans le fichier pour pouvoir être utilisés :
Nous avons à présent les fonctions nécessaires pour interagir avec la blockchain.
Dans le prochain article nous implémenterons ce service dans un component.
Originally published at medium.com on March 12, 2018.