Développer un smart-contract avec Solidity

 

<div id="author" style=" margin-top: 20px;">
<div class="element">

<img class="wp-image-166 alignleft" src="" alt="" width="100" height="100" />
<h3><strong>"Guillaume"</strong></h3>
<p></p>
<a href="https://facebook.com/cryptoast/" target="_blank" rel="noopener"><img src="https://cryptoast.fr/wp-content/uploads/2017/08/facebook2.png" alt="facebook-cryptoast" width="30" height="30" border="0" /></a> <a href="https://twitter.com/cryptoastblog" target="_blank" rel="noopener"><img src="https://cryptoast.fr/wp-content/uploads/2017/08/twitter2.png" alt="twitter-soothsayerdata" width="30" height="30" border="0" /></a></div>
</div>

 

Table des matières

  1. Prérequis
  2. Mise en place de l’environnement
  3. Développement du smart-contract
  4. Déploiement du smart-contract sur la blockchain Ethereum
  5. Améliorons notre smart-contract
  6. Installation de React et Drizzle
  7. Mise en place de l’interface graphique
  8. Mise en place du rendu React
  9. Créer une interaction avec le contrat

 

Prérequis

Vous n’avez pas besoin de connaissances particulière pour suivre ce tutoriel, nous allons voir ensembles tout ce dont vous aurez besoin pour développer votre premier smart-contract avec Solidity et Truffle.

Malgré tout, des spécifications techniques sont requises, notamment un ordinateur possédant :

  • Window, MacOS ou Linux
  • NodeJS v8.9.4 ou version supérieur

 

Mettre en place notre environnement

Commençons par installer Truffle, lancez simplement dans une console la commande suivante :

npm install truffle -g

Une fois Truffle installé, nous pouvons créer notre projet HelloWorld :

mkdir HelloWorld-Tutoriel
cd HelloWorld-Tutoriel
truffle init

Commandes qui doivent être affichées en retour :


✔ Preparing to download
✔ Downloading
✔ Cleaning up temporary files
✔ Setting up box
Unbox successful. Sweet!
Commands:
Compile:        truffle compile
Migrate:        truffle migrate
Test contracts: truffle test

 

Vous voilà avec un projet Truffle, qui contient plusieurs fichiers et dossiers prêts à l’emploi que nous allons voir ensemble : le dossier contracts qui accueillera nos futurs smart-contracts, avec l’extension .sol pour Solidity, le dossier migrations qui contiendra les différents script de déploiement sur la blockchain, test qui nous permettra de réaliser des tests unitaires sur nos contrats et enfin truffle-config que l’on utilisera notamment pour définir la/les blockchains sur lesquels déployer nos contrats.


.
├── contracts
│   └── Migrations.sol
├── migrations
│   └── 1_initial_migration.js
├── test
└── truffle-config.js
3 directories, 3 files

 

Développer notre smart-contract

Ajoutons un fichier HelloWorld.js à notre dossier contracts, et développons un premier smart-contract tout simple.


pragma solidity ^0.5.0;

contract HelloWorld {

    string public sentence;

    constructor() public {
        sentence = "HelloWorld !";
    }

    function saySomething() public view returns(string memory){
        return (sentence);
    }
}

Rapidement, ce smart-contract garde en mémoire une phrase à exprimer, par défaut cette phrase est “HelloWorld !” mais par la suite on pourra la modifier, en ajoutant, par exemple une fonction qui prendrais une nouvelle affirmation en paramètre.

Mettons à jour le dossier migrations en supprimant le fichier présent et le remplaçant par le suivant, 2_deploy_contract.sol :

const Migrations = artifacts.require("Migrations");
const HelloWorld = artifacts.require("HelloWorld");

module.exports = function(deployer) {
  deployer.deploy(Migrations);
  deployer.deploy(HelloWorld);
};

Ce que nous permet Migration est tout simplement de déployer nos contrats sur la Blockchain. Lorsque nous l’appelons il va permettre la créations d’instances de notre contrat via la blockchain, ici c’est une version très simple de fichier de migrations. En revanche, par la suite ce type de fichier peut être améliorer pour, par exemple, déployer plusieurs instances, avec des paramètres particuliers de nos contrats.

Voilà notre premier smart-contract est déployé, passons à la suite afin de le tester.

 

Tester notre smart-contract

Afin de pouvoir tester notre programme, nous allons utiliser les fonctionnalités de Truffle. Lançons le CLI de Truffle :


truffle develop

Vous devrez obtenir une dizaine d’adresses comme ceci :


Truffle Develop started at http://127.0.0.1:9545/
Accounts:
(0) 0x20e8c3840f2da66a9af6f19b92dfe6acd7220979
(1) 0x9ec8cf0a9331c76ae9ed0a930af1eb82a5634476
(2) 0x3edc49fc8b742b7aa9a3043640a939742b3ac5ff
(3) 0xf9215048532a691c374220b9ecc6c902a5052a2a
(4) 0x59cb5b18087f559cf94897903715194cb15c0f97
(5) 0x9c5d882d440097ebb8facb40a897faeb9fe28f4f
(6) 0xc8640f7d2b672d5876cad50a04b1cdb564efc8cb
(7) 0x265c3c05f572a43393615e0d031eab17479ae2dc
(8) 0x606fcc2fb9cfd1b58799c9e0cbc2eefcd824277d
(9) 0x2cd2f8e85790ba2349c105925b90268492f450d6
Private Keys:
(0) d33dbf8d08e64adbfd68f5840693e0652e0f1626e9298a3e84e0df0c9a6a608b
(1) 300beb1a4157b1f28dd237c509e329ca9b2af0fa4bd163fba28df7711764f45b
(2) 087d05212634c8b5954537271f8ac2e6b62071d69234a8a994a575c6d5e013c5
(3) 56fdfc72607fdcac401d39ad673b07f3b8751c72407f044c4b065b4e25ff7eee
(4) afbf4d0a4ca2f534b360d50028421e299b0db836485da07f5fc321e694701342
(5) 21f81e7a3c0bfc0eba20669b9cd60e354fbcd94b363fb12de98e2017406d258b
(6) 17cdb0dec911f3d7641b6e31769a923b2bb9120a3db03b9bfd65d73052a8065a
(7) ccaca67c49100339fbe43c4fc7e4c021f57e2ec63597351a9df763ea724a0277
(8) c9eb955b1fc331e011fe66f22eec4f3b194e585cefd37a14ad6dea3d90b1ad7e
(9) 8d39227ffb2344cf6a501d86780fe35bff596b516492d4937a3bbfc76d93c9a4
Mnemonic: novel grass proof tree crime rough mixed assume indicate paddle peace jazz
⚠️  Important ⚠️  : This mnemonic was created for you by Truffle. It is not secure.
Ensure you do not use it on production blockchains, or else you risk losing funds.

Nous avons dix nouvelles adresses Ethereum, possédant chacune 100ETH afin de pouvoir tester notre smart-contract. Pour se faire nous aurons besoin de le compiler, puis le migrer sur notre blockchain de test. Voilà les commandes :


compile
migrate

Notez que migrate appellera compile, et que l’options –reset peut être utile pour relancer le procédé sur des contrats déjà déployés.

 

Vous devrez avoir une réponse qui ressemble à ça :


Compiling your contracts...
===========================
> Compiling ./contracts/HelloWorld.sol
> Artifacts written to /home/g_chanut/Blockchain/HelloWorld-Tutoriel/build/contracts
> Compiled successfully using:
- solc: 0.5.0+commit.1d4f565a.Emscripten.clang
Starting migrations...
======================
> Network name:    'develop'
> Network id:      5777
> Block gas limit: 0x6691b7
2_deploy_contract.js
====================
Replacing 'Migrations'
----------------------
> transaction hash:    0xe4695301188c58439cf427d4bed1cb923bc734d2f8481658bb384b25ae59a367
> Blocks: 0            Seconds: 0
> contract address:    0xd1BF65181Ca91999bf2E13D45E084CEC4e32BC69
> account:             0x20e8c3840f2DA66A9Af6F19B92Dfe6ACD7220979
> balance:             99.98211062
> gas used:            284844
> gas price:           20 gwei
> value sent:          0 ETH
> total cost:          0.00569688 ETH
Replacing 'HelloWorld'
----------------------
> transaction hash:    0x843f7a25e1dfd80832f2ddcd8ff1ad38c90d91b709e79f8fbb1fd992e6d308e6
> Blocks: 0            Seconds: 0
> contract address:    0x9C96Fa5280d85996dB48AF01B993f640d24D5C6c
> account:             0x20e8c3840f2DA66A9Af6F19B92Dfe6ACD7220979
> balance:             99.97645568
> gas used:            282747
> gas price:           20 gwei
> value sent:          0 ETH
> total cost:          0.00565494 ETH
> Saving migration to chain.
> Saving artifacts
-------------------------------------
> Total cost:          0.01135182 ETH
Summary
=======
> Total deployments:   2
> Final cost:          0.01135182 ETH

Truffle nous affiche donc les différents contrats qui ont été compilés, puis déployés. Dans notre cas il s’agit seulement de HelloWorld. Nous avons également plusieurs informations :

  • Le hash de la transaction qui a déployé notre contrat.
  • L’adresse de notre contrat, une donnée importante, primordiale si notre contrat était un Token.
  • L’adresse de notre portefeuille, puisque nous sommes le propriétaire du contrat.
  • Ce que notre portefeuille contient après avoir payé les frais de déploiement.
  • Les frais de transactions en questions.

Si tout c’est bien passé, notre contrat est prêt à être utilisé ! C’est une grande étape de déployer un contrat sur une Blockchain, vous avez mis en ligne un système immuable.

Pour l’instant, notre contrat est là, quelque part. Mais ne pas pouvoir le voir, interagir avec lui peut être frustrant non ? Sans partir pour l’instant dans le développement d’une interface graphique, ce que nous verrons plus tard, allons rencontrer notre contrat. Rentrez dans la console Truffle, avec la commande Truffle develop :


truffle(develop)> let Hello = await HelloWorld.deployed()
truffle(develop)> Hello.saySomething()

Vous devrez avoir comme réponse :


'HelloWorld !'

Felicitation

 

 

Super ! Nous avons réalisé notre première interaction avec notre smart-contract ! Certes il est très simpliste, mais vous apprendrez rapidement à l’améliorer et à le faire interagir avec d’autres smarts-contracts.

 

Améliorons notre smart-contract

On va pouvoir ajouter une fonction qui permettra de modifier la phrase que la fonction saySomething nous renvoie, fonction qui prendra en paramètre un string.


function changeSentence(string memory newSentence) public {

sentence = newSentence;

}

On pourrait également ajouter une seconde variable, comme un interlocuteur avec qui notre contrat discutera :


string public userName

Il faudra donc modifier notre fonction saySomething afin de prendre en compte ce nouveau paramètre.


function saySomething() public view returns(string memory){

return (sentence + userName);

}

Si vous essayez de compiler le contrat, vous devriez obtenir une erreur de la part de Truffle. En effet Solidity n’aime pas la concaténation de deux string par le ‘+’. Pour régler ce problème, nous avons deux solutions, utiliser une librairie externe, ou créer notre propre fonction de concaténation.

Voici concat, qui va nous permettre d’afficher nos deux paramètres :


    function concat(string memory _base, string memory _value) internal pure returns (string memory) {
           bytes memory _baseBytes = bytes(_base);
           bytes memory _valueBytes = bytes(_value);

           string memory _tmpValue = new string(_baseBytes.length + _valueBytes.length);
           bytes memory _newValue = bytes(_tmpValue);

           uint i;
           uint j;

           for(i=0; i<_baseBytes.length; i++) {
               _newValue[j++] = _baseBytes[i];
           }

           for(i=0; i<_valueBytes.length; i++) {
               _newValue[j++] = _valueBytes[i];
           }

           return string(_newValue);
}

Plus qu’à l’ajouter à notre contrats, modifier saySomething afin qu’il nous retourne bien les deux informations que l’on stocke. Au final votre contrat devrait ressembler à celui là :



pragma solidity ^0.5.0;

contract HelloWorld {
    string public sentence;
    string public userName;

    constructor() public {
        sentence = "HelloWorld !";
        userName = "Guillaume";
    }

    function saySomething() public view returns(string memory){
        return (concat(sentence, userName));
    }

    function changeSentence(string memory newSentence) public {
        sentence = newSentence;
    }

    function concat(string memory _base, string memory _value) internal pure returns (string memory) {
           bytes memory _baseBytes = bytes(_base);
           bytes memory _valueBytes = bytes(_value);

           string memory _tmpValue = new string(_baseBytes.length + _valueBytes.length);
           bytes memory _newValue = bytes(_tmpValue);

           uint i;
           uint j;

           for(i=0; i<_baseBytes.length; i++) {
               _newValue[j++] = _baseBytes[i];
           }

           for(i=0; i<_valueBytes.length; i++) {
               _newValue[j++] = _valueBytes[i];
           }

           return string(_newValue);
       }

}

 

Et voilà, nous avons un contrat plus intéressant avec lequel travailler, on va pouvoir passer à la suite et installer tout ce dont on aura besoin pour développer notre interface graphique.

 

Installation de React et Drizzle

React

Si vous n’avez pas encore Truffle, je vous invite à consulter les premières parties de ce tutoriel afin de le mettre en place sur votre ordinateur. Nous allons installer React, afin de commencer à travailler avec :


npm install -g create-react-app

Puis dans le dossier de votre projet HelloWorld-Tutoriel, lancez la commande suivante afin de crée une application React au sein de ce dernier :

npx create-react-app client

Voici à quoi devrait ressembler votre dossier désormais :


.
├── build
├── client
├── contracts
├── migrations
├── node_modules
├── package-lock.json
├── test
└── truffle-config.js
6 directories, 2 files

Vous pouvez déjà tester si tout fonctionne en vous déplaçant dans le dossier client et lançant React :


cd client

npm start

Vous devriez avoir un onglet qui s’ouvre automatiquement qui vous affiche cette page :

Résultat attendu :

React Start page

 

Voilà React est installé et parfaitement fonctionnel, nous allons maintenant installer Drizzle et l’intégrer rapidement à notre application React. Restez dans le dossier client afin de lancer la commande suivante :


npm install drizzle

Tout est maintenant prêt pour développer notre interface graphique, rendez vous dans le prochain chapitre !

Drizzle

 

Mise en place de l’interface graphique

Avant de pouvoir interagir avec nos contrats, il faut pouvoir faire le lien entre ces derniers et notre application React. Pour ce faire nous allons ouvrir le fichier index.js qui se trouve dans le dossier client/src. Ajoutons les importations dont nous avons besoins, Drizzle et notre contrat HelloWorld :


import { Drizzle } from "drizzle";

import HelloWorld from "./contracts/HelloWorld.json";

 

Puis Drizzle et les options dont nous avons besoins, comme notre contrat et la blockchain sur laquelle il est déployé.

const options = {

contracts: [HelloWorld],

web3: {

fallback: {

type: "ws",

url: "ws://127.0.0.1:9545",

},

},

};

const drizzle = new Drizzle(options);

Plus qu’à ajouter Drizzle dans la déclaration de l’application React et nous arrivons à un index.js qui ressemble à ça :


import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';

import { Drizzle } from "drizzle";
import HelloWorld from "./contracts/HelloWorld.json";

const options = {
  contracts: [HelloWorld],
  web3: {
    fallback: {
      type: "ws",
      url: "ws://127.0.0.1:9545",
    },
  },
};

const drizzle = new Drizzle(options);

ReactDOM.render(, document.getElementById('root'));
serviceWorker.unregister();

 

Nous avons configuré Drizzle sur notre application, mais si essayez de lancer l’application, vous allez obtenir l’erreur suivante :


Module not found:
Can't resolve './contracts/HelloWorld.json' in 'HelloWorld-Tutoriel/client/src'

Et c’est normal, à aucun moment le .json de notre contrat ne va dans le dossier client/src, et react ne nous permet pas d’importer des fichier en provenance d’autres dossier client. Nous avons deux solution, l’une étant de simplement copier coller les json de nos contrats à chaque fois que nous les migrerons, ce qui peut être rapidement chronophage. L’autre solution sera de modifier le fichier truffle-config.js en paramétrant la destination de ces derniers :

const path = require("path");
module.exports = {
 contracts_build_directory: path.join(__dirname, "client/src/contracts")
};

Relancez Truffle et réalisez une nouvelle migration :

truffle develop
migrate --reset

Et relancez l’application :


npm start

Vous ne devrez plus avoir d’erreurs, mais rien a changer à l’écran. En effet même si Drizzle est bien configuré, nous n’avons absolument pas modifier app.js, et le logo React continue de tourner sur lui même, corrigeons ça dans la prochaine partie.

Mise en place du rendu React

En effet, c’est l’application React qui affiche ce que l’utilisateur va observer sur son écran, modifions la ensemble. Voici notre nouvel app.js :

 

 

Nous avons importé un component React HelloWorld, dont nous nous occuperons par la suite, mis en place Drizzle afin de récupérer les données de notre smart-contract. Par la suite nous affichons ce que nous renvoie le component HelloWorld. Voyons ce que contiendra ce dernier, et à quoi ressemblera l’affichage des données de notre contrat.

Ajoutez un nouveau fichier dans le répertoire src du client , et appelez le HelloWorld.js :

 

 

Concrètement, on a simplement récupéré les informations via Drizzle. On appelle notre fonction saySomething en utilisant en paramètres notre adresse Ethereum, puis on affiche simplement le résultat directement à l’écran.

Par la suite nous allons voir ce que cela donne sur notre navigateur, assurez vous d’avoir bien déployé votre contrat dans la console truffle develop .


migrate --reset

Lancez votre application React :


cd client
npm start

Vous devrez avoir un nouvel onglet, qui vous affiche cette page :

helloWorld

 

C’est pas mal ! On récupère bien les données de notre smart-contract et on les affiche à l’utilisateur. Mais rien de très sexy non plus, on ne permet pas d’interaction avec le ce dernier et le contrat, alors que nous avons une fonction rien que pour cela, changeSentence. On va remédier à cela dans la dernière partie de cet article, qui va nous permettre de récupérer des informations de la part de notre utilisateur.

 

Créer une interaction avec le contrat

Avant tout chose, un peut d’installation, on aura besoin pour ce que l’on va faire d’utiliser des boutons, et donc des librairies associé, dans le dossier client, installez react boostrap.  Ce n’est pas obligatoire, mais ça nous permet de découvrir comment utiliser une librairie en React. Une librairie Javascript (le langage dont découle React) est une caisse à outils déjà développer qui nous facilite la vie. Et ça évite de recréer la roue à chaque nouveau projet.


npm install react-bootstrap

Maintenant, ajoutons une interaction entre l’utilisateur et le contrat, on va lui permettre de modifier la variable sentence de son contrat. Je vous donne le code comme ça, on verra ce que l’on a modifié ensuite :

 

Nous avons ajouté deux choses coté graphique, un input qui va récupérer la nouvelle phrase, et un bouton pour envoyer cette dernière. Une fois le bouton appuyé, nous lançons une nouvelle transaction, qui va appeler la fonction changeSentence de notre smart-contract, avec comme paramètre ce que l’utilisateur aura rentré en amont. Résultat, vous pouvez essayer, la phrase est bien modifiée dans notre contrat !

 

défault

Paramètres par défaut

 

phrase-modifie

Une fois la phrase modifiée

 

 

Félicitation, vous avez votre première interaction utilisateur -> contrat, vous pouvez désormais améliorer l’UI, travailler sur des contrats plus complexes, mais la base est là. Merci d’avoir suivi ce tutoriel jusqu’au bout, nous allons voir dans les prochains comment déployer notre DAap sur une blockchain précise, par exemple TomoChain. Il nous reste encore beaucoup à découvrir dans le monde du développement de la blockchain.

 

Voilà, c’est tout pour cet article, nous avons vu comment développer une interface graphique à des smarts-contract.  si vous avez apprécier mon travail, hésitez pas à m’en faire part ! Je suis également preneur de sujets d’articles.

Vous pouvez récupérer le code de cet article sur un repository github.

 

Découvrez tous nos articles pour développer sur Ethereum

Guillaume

Guillaume est un jeune développeur Blockchain, principalement sur Solidity. Il aime partager ses connaissances sur le sujet et il participe activement au rayonnement des aspects techniques de la blockchain au sein de la communauté crypto.

facebook-cryptoast twitter-soothsayerdataProfil linkedinEnvoyer un mail


Poster un Commentaire

avatar