Construire une application mobile connectée à une Blockchain

Chez SQLI, nous croyons à la Blockchain dès maintenant et de la manière la plus simple possible : depuis nos smartphones.

La Blockchain fait rêver, à la fois par la potentielle révolution qu'elle pourrait apporter à la société, tout en paraissant inaccessible. En effet, nombre d'études ou de POC internes conduisent à la même conclusion couperet : immature et/ou trop compliquée. S'en suit un rejet de la technologie en attendant une plus grande maturité.

Le Bitcoin montre pourtant que les principes techniques fondamentaux des Blockchains fonctionnent, mais il paraît trop éloigné de nos usages quotidiens pour avoir l'air de s'appliquer à d'autres domaines. Chez SQLI, nous croyons à la Blockchain dès maintenant et de la manière la plus simple possible : depuis nos smartphones.

Accéder avec la Blockchain avec son smartphone, vraiment ?

Il existe de nombreuses applications qui permettent d'accéder à la Blockchain, mais l'immense majorité est dédiée aux postes de travail et autres ordinateurs de bureau ou portables. En effet, ce sont des applications dites "lourdes", car les ressources nécessaires au fonctionnement de la Blockchain sont importantes : espace disque (plusieurs giga-octets), bande passante réseau (ces giga-octets sont à télécharger ...), mémoire, CPU ...

Le défi de l'accès à la Blockchain au travers d'un smartphone est donc conséquent. Comment concilier ces ressources nécessaires avec les "faibles" moyens apportés par les smartphones ?

Pour y répondre, nous avons donc relevé le défi de construire une application mobile décentralisée Android, qui interagit directement avec une Blockchain, et non pas au travers d'un intermédiaire qui délocaliserait l'accès à Blockchain sur un serveur, dans le Cloud ou sur le serveur de votre choix, fusse-t-il open-source.

Nous avons décidé d'y aller par étape, de manière à rendre progressive la consommation de ressources nécessaires sur le smartphone. Par exemple, pour la première étape, nous nous restreignons à l'usage d'une Blockchain privée, ce qui limite la volumétrie de stockage et la bande passante nécessaire. De plus, nous faisons en sorte que le smartphone soit un noeud passif de la Blockchain, le plus passif possible, qui permet donc uniquement de générer des transactions sur la Blockchain et stocke une partie des blocs qui y sont générés. Par conséquent, le smartphone est un noeud qui ne mine pas.

Passons maintenant à la réalisation d'une application, dont nous avons démontré la faisabilité au Devfest Nantes 2016.

Une application décentralisée Android Ethereum

Pour créer une application décentralisée (ÐApp) sur smartphone Android, nous avons besoin de plusieurs éléments :

  • Une application Android suivant une architecture particulière
  • Un client qui implémente le protocole de communication et de gestion d'un noeud blockchain.

Si aujourd'hui il devient possible de mettre en place ces deux briques indépendamment les unes des autres, comment faire pour les lier au sein même d'un smartphone ?

Dans un premier temps il nous faut récupérer le client blockchain compatible pour l'architecture ARM qu'offre la plupart de nos smartphones. Grâce à la communauté Ethereum, nous avons accès à différentes versions du client Geth cross-compilé pour des architectures différentes. Une version au format Android Archive (.aar) est donc disponible au téléchargement. Il s'agit d'une version "wrappée" du binaire permettant simplement de lancer un noeud geth dans une application Android.

Cependant, une fois le binaire lancé, il n'existe aucun outil pour piloter ce noeud depuis une application Android. C'est pour pallier à ce problème que nous avons créé notre propre librairie de communication appelée Ethereum-Java (licence MIT). Cette librairie Java a les caractéristiques suivantes :

  • elle reprend les standards de communication exposés par Web3.js (une librairie javascript offerte par la communauté pour faire communiquer des ÐApp web)
  • elle permet notamment de communiquer en IPC (inter-process communication) depuis l'application vers le noeud
  • elle offre une gestion de flux de données simplifiée graĉe à l'utilisation de RxJava.

Son but est d'abstraire au maximum les échanges entre une application Android et un client blockchain, facilitant ainsi son utilisation pour des développeurs non expérimentés aux notions de la blockchain.

À présent, intéressons-nous aux outils que nous mettons à disposition pour orchestrer toutes ces briques qui composent notre ÐApp mobile.

Lancer un noeud Geth 1.4 dans une application Android

Note : Geth 1.5 sorti le 15 novembre 2016 propose une API totalement revue et incompatible avec ce nous proposons ici. Nous adaptons nos travaux à cette nouvelle version, ceux-ci devraient être disponibles prochainement.

Après avoir récupéré et référencé la librairie Android-Geth dans une application Android, nous avons accès aux outils de lancement du noeud Geth.

Pour pouvoir lancer le noeud Geth au démarrage de l'application, il faut créer sa propre classe SampleApplication qui étend EthereumApplication.

import com.sqli.blockchain.android_geth.EthereumApplication;
 
 public class SampleApplication extends EthereumApplication {
     ...
 }

Cette classe va se charger de démarrer le noeud Geth dans un service Android avec les paramètres suivants :

  • fast
  • lightkdf
  • nodiscover
  • networkid 100
  • datadir avec la valeur getFilesDir().getAbsolutePath() + "/node"
  • genesis
{
 "nonce": "0x0000000000000042",
 "timestamp": "0x0",
 "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
 "extraData": "S Q L I blockchain",
 "gasLimit": "0x8000000",
 "difficulty": "0x500000",
 "mixhash":
 "0x0000000000000000000000000000000000000000000000000000000000000000",
 "coinbase": "0x0000000000000000000000000000000000000042",
 "alloc": { }
}

La classe va également permettre d'être notifiée une fois le service démarré (lorsque le fichier ipc est créé). Cette notification est disponible à plusieurs niveaux : Activity et Application.

Pour la classe SampleApplication, nous devons surcharger la méthode onEthereumServiceReady() pour récupérer cet évènement. Cela permet par exemple d'instancier EthereumJava (qui sera présenté dans la seconde partie de cet article). Il est en effet possible de communiquer uniquement lorsque le noeud est totalement lancé.

Pour récupérer cet évènement dans une Activity, il faut implémenter l'interface EthereumServiceInterface et s'enregistrer auprès de votre SampleApplication.

import com.sqli.blockchain.android_geth.EthereumService;
 
 public class MainActivity implements EthereumService.EthereumServiceInterface{
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         [...]
         SampleApplication application = (SampleApplication) getApplication();
         application.registerGethReady(this);
     }
 
     @Override
     public void onEthereumServiceReady() {
         // Do something when Ethereum node is ready
 
         super.onEthereumServiceReady();
     }
 }

À ce stade, vous avez une application Android et un noeud Geth qui cohabitent dans votre smartphone et vous êtes capables de faire réagir les interfaces de votre application lorsque le noeud est opérationnel.

Accéder au noeud Geth depuis des Activities

Pour le moment, le pont de communication entre l'application et le noeud blockchain n'est pas établi. Pour cela, il faut démarrer la communication IPC Android d'EthereumJava lorsque le noeud est démarré. Dans la surchage de onEthereumServiceReady(), il faut utiliser le builder de EthereumJava en prenant soin de bien choisir le provider AndroidIpcProvider qui permet (comme son nom l'indique) de faire de l'IPC sous Android.

[...]
 public EthereumJava ethereumjava;
 [...]
 public EthereumJava getEthereumJava() {
     return ethereumjava;
 }
 
 @Override
 public void onEthereumServiceReady() {
     ethereumjava = new EthereumJava.Builder()
             .provider(new AndroidIpcProvider(ethereumService.getIpcFilePath()))
             .build();
 
     super.onEthereumServiceReady();
 }  

AndroidIpcProvider prend en paramètre le chemin absolu où se trouve le fichier ipc. Comme présenté précédemment, le fichier se situe dans le répertoire de l'application (ethereumService.getIpcFilePath()).

Grâce à cette architecture, nous avons accès à l'instance d'EthereumJava depuis n'importe quelle Activity via l'appel ((SampleApplication) getApplication()).getEthereumJava().

Piloter le noeud Geth

Le client Geth expose une API de gestion du noeud, décomposée en modules (eth, personal, admin, miner, net,... ). Pour que l'utilisateur de la librairie ne soit pas totalement perdu dans la liste des fonctions disponibles, nous avons fait le choix du même regroupement en module que Web3.js et d'avoir une signature relativement similaire.

Il est donc possible de récupérer les informations sur le noeud :

NodeInfo nodeInfo = ethereumJava.admin.nodeInfo();
nodeInfo.enode //--> enode://id@ip:port
nodeInfo.ip    //--> adresse ip d'écoute du noeud geth
nodeInfo.id    //--> identifiant du noeud geth

ou encore de créer et dévérouiller des comptes :

String password = "passwd";
String accountId = ethereumJava.personal.createAccount(password);
boolean unlocked = ethereumJava.personal.unlockAccount(accountId);

L'API de Geth offre également la possibilité d'appeler les fonctions de manière asynchrone. Pour gérer le multithreading associé et une écriture de code asynchrone fluide, nous avons opté pour la librairie RxJava. Elle se base sur le pattern Observer, avec une API spécifique. Lors d'un appel asynchrone, un Observable est retourné permettant de définir le comportement notre application dans les différents cas du requêtage : nouvelle donnée, terminé ou erreur.

Observable<NodeInfo> observable = ethereumJava.admin.getNodeInfo()
 observable.subscribe(new Action1<NodeInfo>() {
     @Override
     public void call(NodeInfo nodeInfo) {
         System.out.println(nodeInfo);
     }
 });

Vous êtes à présent prêts à développer votre première application Android décentralisée, contenant un noeud blockchain complet. À ce stade, vous pourrez vous connecter à une blockchain depuis votre smartphone, créer des portefeuilles virtuels, émettre des transactions sur le réseau ou encore analyser en profondeur la blockchain.

Important : ce projet est actuellement en cours de développement et vous est proposé en version alpha, non stable. Il est destiné à un usage expérimental et ne doit en aucun cas être utilisé en production.

La librairie va continuer à évoluer. Par exemple, nous souhaitons limiter les contraintes d'architecture de l'application Android en déplaçant le lancement du service Geth en dehors de la classe Application. De plus, pour le moment, toutes les méthodes de l'API exposée par Geth ne sont pas implémentées et le système de threading actuellement en place complique l'utilisation de la librairie dans une application Android.

Dans la suite de cet article, nous verrons comment communiquer avec un smart-contract depuis une application Android au travers d'Ethereum-Java.