Les smart-contracts Ethereum sur Android avec Ethereum-android - Partie 1

Dans l’article précédent, nous avons appris à développer une application Android décentralisée contenant un noeud Geth complet. Ce savoir nous a permis de lire et d’écrire sur la blockchain. Cependant, la particularité d’Ethereum est que la blockchain peut stocker bien plus que des transactions financières : du code exécutable. Ce code est appelé smart-contract.

Mais quelle est cette sorcellerie ?

Un smart-contract est un ensemble structuré d’instructions exécutées selon certaines conditions. Cette notion prend tout son sens dans l’environnement blockchain. En effet, grâce à l’immuabilité de la blockchain et au protocole Ethereum, il devient possible d’enregistrer de façon sécurisée et sûre un contrat entre plusieurs parties. Ainsi, il est par exemple possible de programmer une location de véhicule. Le contrat permet de démarrer la course automatiquement à la réception du paiement du client, et de verser l’argent bloqué durant toute la durée du transport, sur le compte du propriétaire. Nous vous raconterons cette histoire très prochainement sur ce blog et il ne s’agira que d’une application des smart-contracts parmi les nombreuses possibles.

Vous pouvez également interagir avec un smart-contract déployé sur une blockchain avec Ethereum-android. La librairie permet d’appeler des fonctions du smart-contract via une transaction (persistance de la modification de l’état du smart-contract) ou via un appel local (sans persistance).

C’est l’histoire d’un compteur

Prenons l’exemple d’un smart-contract compteur, implémenté en langage Solidity et présenté ci-dessous.

contract Counter {


     int public counter;
     event fivesMore(int);
 
     function Counter(){
         counter = 0;
     }
 
     function increase() {
         counter++;
         if (counter % 5 == 0) {
             fivesMore(counter);
         }
     }
 }

Ce contrat présente :

1 constructeur Le constructeur Counter permet d’initialiser la valeur du compteur à 0.

1 attribut L’attribut counter ayant la visibilité public, un getter est automatiquement généré

1 événement L’événement fivesMore va permettre d’être notifié à chaque fois que le compteur passe par un multiple de 5

1 fonction La fonction increase permet d’incrémenter de 1 la valeur du compteur, et générer l’événement dans les conditions présentées précédemment.

Mais d’abord…

Il est indispensable de déployer en amont le contrat sur la blockchain car Ethereum-android ne le permet pas pour le moment. La communauté Ethereum a dévelopé un compilateur Solidity en ligne capable de s’exécuter dans un navigateur. Cet outil permet d’écrire des smart-contracts, de les compiler, d’obtenir le code compilé et même d’exécuter le contrat en local (dans le navigateur), ou sur une blockchain particulière via une connexion RPC à un noeud existant. Un mode debug extrêmement détaillé est également disponible pour exécuter pas à pas les fonctions du contrat. Une fois le code compilé, l’outil propose un script de déploiement du smart-contract destiné à l’interpréteur Javascript de Geth. Vous n’avez donc plus qu’à copier ce script et à le coller dans l’interpréteur.

var abi = [{"constant":true,"inputs":[],"name":"counter","outputs":[{"name":"","type":"int256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"increase","outputs":[],"payable":false,"type":"function"},{"inputs":[],"type":"constructor","payable":true},{"anonymous":false,"inputs":[{"indexed":false,"name":"","type":"int256"}],"name":"fivesMore","type":"event"}]
 
 var counterContract = web3.eth.contract(abi);
 
 var counter = counterContract.new(
    {
      from: web3.eth.accounts[0],
      data: '0x60606040525b60006000600050819055505b60eb8061001e6000396000f360606040526000357c01000000000000000000000000000000000000000000000000000000009004806361bc221a146043578063e8927fbc14606857603f565b6002565b34600257605260048050506079565b6040518082815260200191505060405180910390f35b34600257607760048050506082565b005b60006000505481565b600060008181505480929190600101919050555060006005600060005054811560025707141560e8577ff03531ad6936549968376919da10d248674616fc5ee69f701033f6796aaa9aba6000600050546040518082815260200191505060405180910390a15b5b56',
      gas: '4700000'
    }, function (e, contract){
     console.log(e, contract);
     if (typeof contract.address !== 'undefined') {
          console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
     }
  })

L’interface du contrat (var abi…) ainsi que son adresse (contract.address) devront être renseignées dans l’application Android. Vous obtiendrez l’adresse dans les logs de l’interpréteur comme spécifié dans le script ci-dessus (Code : console.log(‘Contract mined! address: ‘ + contract.address[…]);), ou bien en appelant counter.address dans l’interpréteur. L’adresse n’est disponible qu’une fois que la transaction du déploiement du contrat a été prise en compte par un mineur.

Étape 1

La première étape pour pouvoir faire appel à un contrat depuis l’application Android est de convertir l’interface du contrat du format Json (var abi…) en Java. Cette interface équivalente est :

interface Counter extends ContractType {
 
     @SolidityEvent.Anonymous(false)
     @SolidityEvent.Parameters({
         @SolidityEvent.Parameter(indexed = false, name = "fivesMore", type = SInt256.class)
     })
     SolidityEvent<SInt256> fivesMore();
 
     @SolidityFunction.ReturnType(SInt256.class)
     SolidityFunction<SInt256> counter();
 
     @SolidityFunction.ReturnType(SVoid.class)
     SolidityFunction<SVoid> increase();
 }

Nous pouvons noter qu’il s’agit d’une interface Java qui étend le type ContractType et que chaque méthode de l’interface correspond aux fonctions exposées par notre smart-contract. Les méthodes retournent des SolidityFunction et des SolidityEvent.

Dans l’idée du compteur sur la blockchain, nous pourrions appeler la fonction counter() sans persistance et increase() avec persistance afin de respectivement récupérer et modifier la valeur du compteur.

Chaque SolidityFunction est annotée par ReturnType. Ce qui permet de spécifier le type de retour de façon statique car le type générique d’un objet Java est perdu à la compilation et non disponible au runtime.

Guillaume Nicolas

Ingénieur Développeur, SQLI Nantes

1 réponse
  1. Julie dit :

    Merci pour votre article et ces informations intéressantes, pourriez-vous donner plus d’exemples de smart contracts possibles avec ethereum et sa blockchain ? Merci à vous.

    Répondre

votre commentaire

Se joindre à la discussion ?
Vous êtes libre de contribuer !

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Inscription newsletter

Ne manquez plus nos derniers articles !