Social_Network_Analysis_Visualization.png
< < Articles

Industrialisation de smart contracts avec Truffle

-/-/-

You can also read this article in English.

Cet article est le premier d’une série sur les réseaux BlockChain. Il s’adresse à un public possédant déjà des connaissances sur le fonctionnement d’un réseau BlockChain et des Smart Contracts Ethereum.

Depuis l’incident du Hack de la DAO, la sécurisation des smart contracts est devenue un enjeu important dans le développement d’applications décentralisées sur Ethereum. Un des moyens de sécuriser est la mise en place un processus d’industrialisation de ces smart contracts. Nous allons voir comment automatiser les tests unitaires, fonctionnels ou d’intégration. Une fois que nous aurons ce processus d’industrialisation, nous pourrons automatiser nos tests de sécurisation. Nous utiliserons Truffle pour mettre en place notre processus d’intégration continue ; ce qui nous permet de valider chacune des modifications apportées à notre code par rapport à nos exigences de qualité.

Truffle est  un framework de développement Ethereum (créé par ConsenSys, l’entreprise co-fondée par Vitalik Buterin). Il permet d’interfacer des smart contracts avec du code JavaScript et l’ensemble de l’écosystème NodeJS. Cela ouvre donc la voie à l’utilisation des outils d’industrialisation du monde JavaScript pour la chaîne de blocks Ethereum.

Truffle apporte les fonctionnalités suivantes :

  • Gestion des dépendances (au travers de NPM ou EthPM - le package manager Ethereum de smart contracts)
  • Compilation des contrats
  • Migrations
  • Tests (2 modes possibles)

      <li style="font-weight: 400;">
        En JavaScript, pour valider votre contrat depuis l’extérieur à l’aide de Mocha et Chai.
      </li>
      <br /> 
      
      <li style="font-weight: 400;">
        En Solidity, pour valider votre contrat depuis l’intérieur (depuis le réseau directement).
      </li>
      <br />
      

  • Interaction avec les contrats en JavaScript

      <li style="font-weight: 400;">
        Truffle fournit notamment une console
      </li>
      <br />
      

  • Gestion des différents environnements (networks)
  • Cet ensemble de fonctionnalité nous permet de mettre en place un processus d’industrialisation classique, à savoir : Build > Test > Deploy

    Nous allons voir comment Truffle nous permet de faire cela.

    Préparation

    Tout d’abord, nous aurons besoin de mettre en place un projet. Nous partirons sur le projet de base de Truffle :

    npm install -g truffle ethereumjs-testrpc && truffle init
    

    Vous devriez désormais avoir un projet contenant un dossier “contracts”, un dossier “migrations” et un dossier “test”, ainsi qu’un fichier truffle.js.

    Build

    Afin de déclarer vos smart contracts sur le réseau Ethereum, ce dernier a besoin de connaître leurs fonctions disponibles. Il faut donc générer un fichier JSON pour chacun des smart contracts qui sera l’équivalent d’un fichier header (.h) en C/C++.

    Truffle offre la possibilité de générer ce fichier grâce à la commande :

    truffle build
    

    Gestion des dépendances

    Vos contrats ou votre code JavaScript dépend peut être (sans doute) d’autres paquets. Truffle permet de gérer ces dépendances facilement : une fois déclarées dans le fichier adéquat, vous pouvez les installer à l’aide de truffle install  (pour les dépendances de smart contracts) ou npm install  (pour le JavaScript, rien d’inhabituel ici).

    En résumé, pour builder notre application, rien de plus simple :

    npm install
    truffle install
    truffle build
    

    Note : il peut être plus simple sur le long terme de gérer vos dépendances en customisant le processus de build de Truffle. Ceci sera à adapter en fonction de votre projet, mais permet de n’avoir qu’à entrer la commande truffle build .

    Test

    Les choses se complexifient quelque peu ici : en effet, nous ne voulons pas tester notre code sur le réseau ethereum directement, mais pouvoir voir ce qui se passe. C’est pourquoi nous avons installé le paquet ethereumjs-testrpc lors de la préparation. Celui-ci va nous permettre de simuler localement un réseau Ethereum, et de voir tout ce qu’il s’y passe.

    Pour le lancer, dans un terminal, entrez la commande testrpc , et votre réseau sera disponible localement (sur le port 8545 par défaut).

    TestRPC Output

    Une fois ce réseau allumé, vous pouvez exécuter vos tests de smart contracts avec la commande :

    truffle test
    

    Truffle Test

    Nos tests s’exécutent alors, et nous pouvons voir dans la console testrpc ce qu’il se passe directement.

    TestRPC Test Output

    Pour résumer, de façon à tester notre application nous avons eu besoin des commandes suivantes :

    testrpc &  # permet de lancer en tâche de fond
    truffle test
    

    Note: si vous souhaitez modifier le port pour les tests, rien de plus simple. Lancez testrpc avec l’option -p :

    testrpc -p 8242
    

    puis, dans le fichier truffle.js, modifiez le paramètre port de l’environnement de développement :

    module.exports = {
      networks: {
        development: {
          host: "localhost",
          port: 8242,
          network_id: "*" // Match any network id
        }
      }
    };
    

    Les tests de notre application sont passés, nous pouvons passer à l’étape suivante.

    Deploy

    Après des tests au vert, dans un processus d’intégration continue, vient le déploiement vers une plateforme d’intégration (où un groupe de beta-testeurs pourra l’essayer par exemple). Pour ce faire, il est nécessaire de  déclarer l’environnement dans le fichier truffle.js :

    module.exports = {
      networks: {
        development: {
          host: "localhost",
          port: 8242,
          network_id: "*" // Match any network id
        },
        integration: {
          host: "integration.my-dapp.com",
          port: 80,
          network_id: "*"
        }
      }
    };
    

    Ici, mon environnement “integration” est hébergé sur un serveur distant, joignable à l’adresse “integration.my-dapp.com”. Enfin pour déployer les contrats sur cet environnement, la commande à utiliser est :

    truffle migrate --network integration
    

    Truffle Migrate

    Cette commande aura pour effet de mettre à jour les fichiers JSON du contrat sur cet environnement, puis d’exécuter les migrations déclarées dans le dossier “migrations”. Voici ce qui se déroule sur cet environnement avec ces migrations.

    TestRPC Migrate Output

    Intégration à GitLab CI

    Si vous souhaitez intégrer Truffle à GitLab CI, voici un exemple de fichier qui devrait fonctionner avec l’exemple de départ de Truffle. Dans l’idéal, il faudrait un service testrpc déclaré dans la configuration de votre GitLab CI, ainsi qu’une image docker dédiée pour exécuter les tests contenant truffle. Le processus tel qu’indiqué ci-dessous est un peu long autrement (il faut tout réinstaller à chaque fois).

    image: alpine:latest    # Idéalement, il faudrait une image avec truffle déjà installé
    
    before_script:
      - apk add --no-cache nodejs nodejs-npm git python g++ make
      - npm install -g truffle ethereumjs-testrpc
    
    stages:
      - build
      - test
      - deploy
    
    build:
      stage: build
      tags: [ek-docker]
      script:
        - truffle compile
    
    test:
      stage: test
      tags: [ek-docker]
      script:
        - testrpc -p 8242 &     # On pourrait aussi avoir le testrpc dans un service
        - truffle test
    
    deploy:
      stage: deploy
      tags: [ek-docker]
      script:
        - testrpc -p 8242 &
        - truffle migrate --network integration
    

    Et le résultat une fois dans GitLab CI :

    GitLab CI Truffle pipeline

    Voici en quelques étapes, avec Truffle, comment industrialiser vos projets de Smart Contracts. Vous aurez ainsi une validation automatique de votre code à chaque modification de ce dernier, et pourrez même le déployer automatiquement.

    Prochaines étapes

    Nous pouvons rajouter des vérifications à notre processus, dans l’étape de tests, comme par exemple une intégration à l’outil d’analyse statique Oyente (encore en beta). Cet outil nous permettra d’augmenter notre confiance dans le code que nous avons produit, en nous indiquant si nous respectons les conventions de développement et n’avons pas potentiellement introduit un bug dans notre Smart Contract.

    Les Smart Contracts Ethereum et le langage Solidity sont encore assez récents. Cependant, la présence d’outils d’industrialisation dans l’écosystème nous indique que la technologie arrive à maturité.