TP Blockchain Ethereum - Partie II
Introduction aux Events
Dans un Smart Contract, une fonction appelée peut émettre un événement (event). Les events en plus d'être inscrit dans la blockchain, peuvent être récupéré par un Listener dans l'application en front-end. Cela permet par exemple de notifier l'utilisateur qu'une opération à bien eu lieu.
Pour les travaux qui suivent nous allons nous appuyer sur la librairie ethers.js (au
lieu de web3.js). L'installation se fait à l'aide de la commande npm i ethers
(Attention au proxy Lyon 1 : npm config set proxy "http://proxy.univ-lyon1.fr:3128"
).
Programmation asynchrone
Pour pouvoir mieux appréhender la suite des exercices proposés il est important de comprendre la programmation en mode asynchrone de JavaScript (Promise, async/await). Voici un premier exemple qui permet de récupérer le numéro du dernier bloc miné. Ce bout de code peut être exécuté directement dans la console de node ou avec la commande node suivit du nom du fichier javascript.
const ethers = require('ethers');
const provider = ethers.getDefaultProvider(); // homstead (mainnet)
provider.getBlockNumber()
.then(blockNumber => {
console.log("Block number : " + blockNumber);
});
ou avec le support de Infura
const ethers = require('ethers');
const provider = new ethers.providers.InfuraProvider('homestead','64da4byourprojectid.....');
provider.getBlockNumber()
.then(blockNumber => {
console.log("Block number : " + blockNumber);
});
Observons l'évolution de la blockchain
La première étape consiste a observer en "temps réel" la création de nouveaux
blocs dans la blockchain homestead (mainnet). L'apparition d'un nouveau bloc est un event en soi.
Soit le fichier index.js
.
const ethers = require('ethers');
const provider = ethers.getDefaultProvider(); // homstead (mainnet)
provider.on('block', (blockNumber) => {
console.log('-- New Block: ' + blockNumber);
});
Observons la naissance des chats (CK)
Il existe un Smart Contract (ERC-721) à l'addresse
0x06012c8cf97BEaD5deAe237070F9587f8E7A266d
qui permet de collectionner des
CryptoKitties (chat électronique). L'application frontal
(https://www.cryptokitties.co/) permet aux utilisateurs d'en acheter, d'en vendre (spéculation),
ou de les faire se reproduire afin de créer de nouvelles générations de
"chats". Le code source du Smart Contract qui permet cela est disponible à l'adresse
0x06012c8cf97bead5deae237070f9587f8e7a266d.
Si vous parcourez le code Solidity de ce Smart Contract (lignes 226 et 415) vous observerez qu'un
évenement Birth
est émis à chaque fois qu'un "chat" naît. Le code source JavaScript
suivant permet d'observer la naissance des chats en temps réel.
const ethers = require('ethers');
const provider = ethers.getDefaultProvider(); // homstead (mainnet)
let abi = [
"event Birth(address owner, uint256 kittyId, uint256 matronId, uint256 sireId, uint256 genes)"
];
let contractAddress = "0x06012c8cf97BEaD5deAe237070F9587f8E7A266d";
let contract = new ethers.Contract(contractAddress, abi, provider);
contract.on("Birth", (owner, kittyId, matronId, sireId, genes , event) => {
console.log("# block # : " + event.blockNumber);
console.log("# Owner : " + owner);
console.log("# kittyId : " + kittyId);
});
Vous devrez peut être patienter quelques longues minutes avant qu'un "heureux
événement" ne se produise. Ensuite, avec l'addresse du propriétaire et etherscan.io
vous devriez pouvoir observer la transaction sur la blockchain, son coût et
surtout à quoi ressemble le "chat" nouveau-né (cf. onglet Inventory).
Travail facultatif :
- Écrivez un bout de code qui affiche le numéro de chaque nouveau bloc miné, et
- si ce bloc contient la naissance d'un chat, affichez l'adresse Ethereum de son propriétaire et l'Id du chaton.
A vous d'observer ! (ERC-20)
Les contrats ERC-20 définissent un événement Transfer(address indexed _from,
address indexed _to, uint _value)
appelé par toutes les fonctions de transfert
de Token d'un compte à un autre (i.e. transfer(...)
et transferFrom(...)
).
Choisissez le Token de votre choix (ex: BAT, ZRX, ...) et en vous inspirant des exemples précédents, écrivez un bout de code Javascript qui affiche le nombre de Token transmis (value) entre les comptes en temps réel.
Travail à rendre :
- Écrivez un bout de code qui affiche le numéro de chaque nouveau bloc miné
- Si ce nouvea bloc contient une transaction du Token que vous avez choisi profitez en pour afficher les adresses de l'émetteur et du récepteur ainsi que la valeur transmise.
- Pourquoi pour ce second TP nous n'avons pas eu besoin de récupérer des Ethers au préalable ?
Travail de réflexion :
Comparez le coût en unité de GAS de l'OP_CODE SSTORE et de l'OP_CODE LOG (utilisé par la fonction emit d'un événement) :
- Qu'est ce que cela vous inspire ?
- Quelle est la limitation ?