Staging wordpress dev & prod

Vous développez un site mais celui ci est en production. Comment faire pour le modifier sans risquer de le faire sauter ? Généralement pour le code on utilises git, mais pour tester votre code il vous faut une copie du site. Le cycle est le suivant :

  • je fais une copie du site de production vers mon site local (avec docker je m’assures que l’environnement serveur est le même), code et base de donnée
  • je fais mes corrections, je teste (idéalement avec outil de tests automatisés, tel behat)
  • je renvoies le nouveau code sur le site de production (via git), en incluant les mises à jour de base de donnée, mais je n’envoies pas la base elle même

Rien de bien compliqué en apparence mais voila, il y a un hic, comment faire si, par exemple, j’ai une boutique woocommerce et que je veux utiliser un moyen de paiement factice, ou d’autres modules que je dois paramétrer différemment en local (comme par exemple l’envoies de notifications email) ?

Je vais devoir configurer mon wordpress légèrement différemment, et à chaque fois que je vais récupérer la dernière BDD de prod, je vais devoir changer tous ces paramètres un par un. A moins que …

Voici la configuration que j’utilise pour faire du staging wordpress :

  • Avec le plugin updraft plus : une fois un FTP ou un S3 configuré, on peut très facilement faire une sauvegarde d’un coté et une restauration de l’autre
  • Je met dans mon wp-config.php du site local
    define( ‘WP_HOME’, ‘https://xxx’ ); define( ‘WP_SITEURL’, ‘https://xxx’ );
  • Avec le plugin Velvet Blues Update URLs je fais une passe sur le contenu en base
  • Avec JSON Options (et Get Options pour savoir lesquelles) j’ai un moyen d’exporter la configuration spécifique au site local
  • Avec WP dev flag je met un bandeau afin de différencier visuellement le site local du site de production (ce qui évite bien des erreurs d’inattentions, indispensable)

Et voila, le tour est joué.

PS : si jamais vous ne voulez pas activer les même modules par défaut sur les 2 sites, je vous conseille ce lien.

Stack web PHP pro open source complète

Vous avez un serveur, nu, qu’est-ce qu’on installe dessus pour mettre en site web en ligne dans un environnement pro ?

Que signifie « pro » exactement d’ailleurs de manière prosaïque ? Il s’agit d’assurer que le site soit toujours en ligne « no matter what » (ce qui implique des backups, des outils de monitoring), et que les développeurs puissent le modifier sans tout faire pêter (donc ils doivent avoir une version « locale » sur leur propre machine de développement, et pouvoir déployer sans risque). Pour assurer ces 2 simples « fonctions » il faut tout un tas d’outils, chacun son rôle. Pour que les développeurs puisse collaborer un faut un gestionnaire de version (git), pour que les chef de projets puisse dire quoi développer il faut un outil de suivie des tâches (gitlab par exemple), pour gérer les différents sites il faut plusieurs machines virtuelles, pour s’assurer que l’environnement de déploiement soit toujours le même on utilise des conteneurs ainsi que des outils de test automatisés pour s’assurer qu’il n’y ai pas de régressions. Il faut des outils d’analyse pour le marketing, pour les performances et pour la sécurité. Enfin il faut des outils de collaboration (messagerie, échange de mot de passe sécurisée, documents collaboratifs).

  • proxmox : gestionnaire de machines virtuelles, gère les clusters, la réplication, les backups
  • pfsense : firewall qui va gérer la sécurisation de l’accès web aux VM
  • squid3 : reverse proxy qui permet de gérer le cache, le load balancing, et le routage
  • docker : c’est l’outil de conteneurisation (éventuellement kubernetes pour les déploiement ou ansible, ou de simples script bash)
  • LAMP : le serveur web, ici pour du PHP, du MySQL en base de donnée, suffisant pour des petits sites, postgres est préférable pour des sites plus costaud
  • wordpress (ou autre) et tout un tas de plugins : updraft plus (backup + migration), matomo, yoast SEO, memcached, postSMTP, contact form7
  • matomo : c’est le google analytics en version open-source. Des plugins payants très intéressants existent aussi
  • behat : pour faire des tests automatisés, indispensable pour s’assurer qu’on n’introduit pas des nouveaux bug quand on rajoute un fonctionnalité ou qu’on corrige un dysfonctionnement
  • gitlab : gestion des tâches et versions pour permettre aux développeurs, au designers et aux chef de projet de collaborer efficacement
  • nextcloud : partage de documents, l’équivalent de dropbox mais en open source
  • keepassx : gestionnaire de mot de passe (bitwarden si on veut la même chose en ligne)
  • mattermost : l’équivalent de slack (il y a aussi rocket.chat)
  • tick : telegraf influxdb chronograf et kapacitor, base de donnée de séries temporelles avec un petit daemon associé pour surveiller tout ce qui se passe sur une machine
  • xhprof : pour faire des diagnostiques de performance si le site est trop lent
  • backstop : test de non régression visuel
  • yslow : outil de test qui diagnostique les mauvaises pratiques qui pénalisent le référencement
  • locust.io : outil de scalabilité. Permet de savoir combien vous pourrez avoir de visiteurs en même temps sur votre site
  • minio : serveur S3, pour les backups. nfs ou smb sont aussi utilisés.

Outils freemium (gratuits et illimités en version de base, mais non open source) :

  • uptime robot : surveille votre site et envoies une alerte s’il tombe en rade
  • cloudflare : protège votre site et l’accélère

Outils payants :

  • mailchimp : newsletter, pour ne pas se faire blacklister
  • hotjar : analyseur de comportement (session recording, heatmap, funnel) / mixpanel / https://plugins.matomo.org/HeatmapSessionRecording

Créer son propre cloud : installer proxmox et une première VM connectée au net sur un serveur kimsuffi

A priori ce tutoriel est valable pour n’importe quel serveur (kimsuffi ou autre) du moment que vous pouvez intaller proxmox VE6 dessus, et pour du proxmox 5 il ne devrait pas y avoir beaucoup de différences

En ce moment je travaille pour deux projets différents, une startup qui a besoin d’un site web, tout ce qu’il y a de plus basique, et pour moi, je souhaite avoir mon propre cloud pour pouvoir tester rapidement des applications auto-hébergées. Dans les deux cas j’ai besoin d’avoir une architecture évolutive. Quand je teste des applications je veux pouvoir créer une VM temporaire, et pour héberger un site web la, des VMs on en a besoin pour tout un tas de choses quand on développe. J’ai besoin d’une solution pour pouvoir installer des VMs sur un serveur distant. Il existe plein de solutions (Xen server, VMWare ESXi, et d’autres … j’avais déjà utilisé vSphere par le passé avec un client en flash ! lol). J’ai choisi proxmox VE 6 (PVE6), gratuit, open source, basé sur KVM et disposant de plein de fonctionnalités interressantes : cluster, snapshot, migration live, interface de gestion web, CLI, et plein d’autres choses (comme Ceph que je ne connais pas encore mais que je vais bientôt étudier).

Kimsuffi, ce sont des serveurs OVH un peu datés avec une interface de gestion minimaliste. En gros vous pouvez installer une distribution dessus et c’est à peu près tout. C’est parfait pour moi, ils proposent PVE6 justement. Je lance, je reçois le mot de passe root et en avant. Il n’y a aucune configuration à faire, je me loggue sur Proxmox et j’arrive sur l’interface de gestion :

Parfait. Maitenant pour créer sa première VM c’est la que les problèmes commencent. D’abord, il me demande un ISO, mais la liste est vide !! Après quelques recherches, je trouve, il faut la télécharger soi même en ligne de commande (Boutton « Shell »). Je prends la dernière LTS ubuntu server :

cd /var/lib/vz/template/iso; wget http://releases.ubuntu.com/18.04/ubuntu-18.04.3-live-server-amd64.iso

Je vous invites à faire un upgrade en passant de proxmox. Kimsuffi installe la v6.0 mais la v6.1 apporte des choses intéressantes, notamment le rechargement de la conf réseau.

apt update; apt upgrade

Maintenant je peux créer ma VM :

Le reste du wizard est simplissime, j’ai mis 2 coeurs, 2Go de RAM, 32Go de disque. Par contre la partie réseau, c’est la que ça s’est compliqué !! Première tentative ma VM s’installe correctement mais je n’ai pas d’accès au réseau. Ouch ! Et configurer un réseau sous linux ce n’est pas ma tasse thé. J’ai galéré. Je suis habitué sous Virtual Box à faire du NAT ou un Bridge avec mes VM et basta. Proxmox propose les même choses mais …

J’ai passé 2 jours entiers à chercher sur les forums et à tester des configurations. Le problème c’est que si vous mettez en l’air le réseau d’un serveur distant … et ben vous êtes bon pour le ré-installer from scratch.

Il y a plusieurs possibilités, installer une VM avec DHCP, utiliser « cloud init » mais le problème c’est que si je n’arrive pas à faire le truc le plus simple, je me vois mal m’engager dans des manoeuvres beaucoup plus compliquées. La plupart des tutos font des suppositions sur votre architecture et les choses évoluent vite (et malheureusement ça sera un peu pareil avec le mien). Bref, voici la solution que j’ai trouvée et qui corresponds à ce qu’on a dans le manuel proxmox. Je vous l’aie condensée en une seule ligne de commande :

cat >> /etc/network/interfaces <<EOF

auto vmbr1
iface vmbr1 inet static
        address  192.168.1.1
        netmask  24
        bridge-ports none
        bridge-stp off
        bridge-fd 0

        post-up echo 1 > /proc/sys/net/ipv4/ip_forward
        post-up   iptables -t nat -A POSTROUTING -s '192.168.1.0/24' -o vmbr0 -j MASQUERADE
        post-down iptables -t nat -D POSTROUTING -s '192.168.1.0/24' -o vmbr0 -j MASQUERADE
EOF

Et voila !

Ha non, n’oubliez pas de rebooter proxmox, sinon il ne prendra pas en compte votre nouvelle interface réseau.

On rajouter un réseau NAT « vmbr1 » qui utilises le réseau pré-configuré vmbr0 par défaut (ça peut être différent dans votre configuration) et ensuite il faut configurer la VM en manuel pour utiliser ce réseau. Le sous-réseau 192.168.1.0/24 sera utilisé (c’est à dire toutes les adresses entre 0 et 254). Les règles iptable servent à transférer de vmbr1 à vmbr0.

Par défaut dans mon fichier de configuration des interfaces j’ai ceci (et on n’y touche pas, il y a plein de tutos qui démarrent avec des IP statiques dans cette partie) :

# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

# The loopback network interface
auto lo
iface lo inet loopback

iface enp1s0 inet manual

auto vmbr0
iface vmbr0 inet dhcp
  bridge-ports enp1s0
  bridge-stp off
  bridge-fd 0

D’abord à la création de la VM pensez bien à mettre vmbr1 :

Ensuite, lors de la configuration d’ubuntu server, il va falloir mettre les bon paramètres (je passe les étapes bidons de choix de la langue) :

Continuer sans le réseau ? ha ben non, pas question, je fais quoi de mon ubuntu server si je n’ai pas le réseau ? Proxmox fournit un accès VNC, soit, mais je ne vais pas aller bien loin avec ça. Donc … à ce stade ma seule solution c’est la configuration manuelle :

C’est la qu’il faut un minimum de connaissance réseaux pour remplir ces cases :

  • subnet: c’est le masque de sous-réseau, ça indique les adresses réseau autorisées
  • address: c’est l’IP de la nouvelle machine dans ce sous-réseau
  • gateway : la gateway c’est un peu comme votre box internet, c’est elle qui fait le routage des requettes internet. Au début je pensais qu’il fallait que je prenne cette de proxmox (donc celle de kimsuffi) avant que je ne réalise que la gateway c’est « proxmox » lui même, c’est à dire 192.168.1.1, l’adresse virtuelle que j’ai définie dans la conf réseau de proxmox.
  • name server : on met généralement l’IP du serveur de google

A partir de la on fini le wizard d’installation d’ubuntu server (moi j’installe sur tout le disque avec les options par défaut). On se retrouve avec un fichier netplan comme suit (/etc/netplan/50-cloud-init.yaml) sur la VM, qui reprends la configuration qu’on a entré à la main. A la rigueur vous pourriez installer ubuntu sans réseau et le rajouter après coup en modifiant le fichier :


network:
	ethernets:
		ens18:
			addresses:
			- 192.168.1.2/24
			gateway4: 192.168.1.1
			nameservers:
				addresses:
				- 8.8.8.8
	version: 2

La, vous avez une machine qui peut se connecter au net, faire ses updates, toussa toussa. Super, mais … est-ce que le net peut communiquer avec votre machine pour autant ? Non car vous êtes en NAT, c’est un réseau privé. Donc si vous installez (comme moi) un site dessus, internet ne pourra pas le voir.

Il faut donc modifier la table de routage pour que le traffic entrant des ports 80 et 443 (les ports généralements utilisés pour server un site web) soit redirigé vers la nouvelle VM. Et pour ça il faut encore aller modifier l’interface réseau de proxmox en rajoutant ces lignes dans vmbr1 :

	post-up iptables -t nat -A PREROUTING -i vmbr0 -p tcp --dport 80 -j DNAT --to 192.168.1.2:80
	post-down iptables -t nat -D PREROUTING -i vmbr0 -p tcp --dport 80 -j DNAT --to 192.168.1.2:80
	post-up iptables -t nat -A PREROUTING -i vmbr0 -p tcp --dport 443 -j DNAT --to 192.168.1.2:443
	post-down iptables -t nat -D PREROUTING -i vmbr0 -p tcp --dport 443 -j DNAT --to 192.168.1.2:443

Cette fois on reboote proxmox et on est bon. Pour tester rapidement si votre serveur réponds bien, petite astuce, utilisé python :

python -m SimpleHTTPServer 80

Si ça réponds sur l’IP ou le nom de domaine de votre serveur, c’est que la configuration de votre VM est correcte et que vous pouvez passer à la suite !

Etape par étape.

Les prochaines fois je prévoies justement d’installer un DHCP ou un « cloud init » parce que devoir modifier la configuration du réseau et rebooter à chaque nouvelle VM ça va vite devenir ennuyeux. Mais, je compte surtout faire un article bientôt sur « rancher », pour faire du SaaS, c’est dire installer des applications web en self hosted très rapidement.

Pour terminer quelques lignes de commande très utiles pour debugger quand ça ne marche pas, parce que oui, quand je lis les tutos personne n’explique jamais quoi faire si leur tuto ne s’adapte pas bien :

Pour tester si votre machine à accès à internet et si un carte réseau fonctionne:

ping -I vmbr0 www.google.fr

Pour avoir votre table de routage (et la gateway actuelle) :

route -n

Si vous modifié (sous ubuntu server) la configuration réseau, pour le redémarrer :

sudo netplan apply

Ce n’est pas grand chose mais quand on ne connait pas (comme moi) c’est bien pratique.

Faire un backup automatique de son wordpress sur son disque dur via FTP

Ce blog est hébergé chez OVH, sous debian 9. Par défaut les plugins de backup de wordpress (j’ai pré-sélectionné UpdraftPlus et BackWPup) me proposent de faire une sauvegarde sur disque. Bien sûr je pourrais louer de l’espace sur un cloud pour une somme modique (par exemple amazon S3 ça ferait du 24€ par mois pour 1To) mais je n’aime pas trop cette idée car je ne vais pas maîtriser mes coûts à priori. Donc, pourquoi ne pas utiliser un espace dédié sur un disque dur de ma machine, sur laquelle je vais installer un protocole qui permet le transfert de fichier ?

Dans cette série nous allons voir comment installer ce bon vieux FTP, puis comment le sécuriser avec FTPS et comment installer un S3 plus moderne avec minio. On démarre avec FTP (inspiré de ce tuto).

Attention, cette méthode n’est pas sécurisée.

Nous verrons plus tard comment faire du FTPS (FTP encrypté).

Tout dabor on va installer vsftpd et un user « remotebackup », dont on va changer le répertoire « home » pour ‘/media/yba/Working/FTP’ (le répertoire dédié aux backups sur mon disque dur « Working »):

sudo apt-get install vsftpd
sudo useradd -m remotebackup
sudo passwd remotebackup
sudo usermod -d /media/yba/Working/FTP remotebackup

Ensuite on va configurer vsftd en modifiant le fichier /etc/vsftpd.conf. On refuse les connections anonymes (il faudra donc un user/mdp pour se connecter, et on arrive directement dans le répertoire local du user) :

listen=YES
listen_ipv6=NO
connect_from_port_20=YES

anonymous_enable=NO
local_enable=YES
write_enable=YES
chroot_local_user=YES
allow_writeable_chroot=YES
secure_chroot_dir=/var/run/vsftpd/empty

pam_service_name=vsftpd

userlist_enable=YES
userlist_file=/etc/vsftpd.userlist
userlist_deny=NO

Comme on précise que la liste des users est dans le fichier /etc/vsftd.userlist il va falloir remplir ce fichier avec :

remotebackup

Enfin on lance le démon :

sudo service vsftd restart

Si votre disque dur est en FAT32 (le mien est formaté en ext4) alors pour que remotebackup puisse en faire sa home il vous faut faire dans /etc/fstab :

/dev/sdc1       /media/yba/HDD  vfat    user,umask=0000   0   0

Notez que vous devez ouvrir le port 21 et 20. Si vous êtes dans mon cas, ça se fait dans le panneau de configuration de la freebox. Sinon avec ufw :

sudo ufw allow 21/tcp
sudo ufw allow 01/tcp

Pour aller plus loin avec ufw (par exemple pour n’ouvrir qu’un port pour une seule appli ou une seule machine) je vous conseille ce tuto.

Kit autonomie forestière électrique

Si comme moi vous faîtes votre propre bois, vous serez peut-être intéressé par ce « kit forestier ». Il suppose que vous ayez des panneaux solaire car il est tout électrique, et l’idée est fonctionner (le plus possible) hors réseau, en autonomie donc.

Du coup vous n’allez pas abattre des forêts entière avec, on est d’accord. L’intérêt ici c’est que ce kit fonctionne qu’il y ai de l’essence à portée de main ou pas. Il émet moins de CO2 (du moins sur le lieu d’utilisation, il faudrait vérifier en terme d’énergie grise). Pour une cabane ou une petite maison bien isolée ça devrait suffire.

J’ai choisis les outils de la game « greenwork tools » que j’utilises depuis plusieurs mois et dont je suis content. J’ai pris ces outils car, du moins à l’époque ou j’avais regardé, greenworks étaient les seuls à proposer une tronçonneuse 40cm, qui en plus existe en version filaire (pour économiser les batteries en finissant de tronçonner à la maison). Les pièces étant interchangeables.

L’avantage c’est qu’on peut utiliser les même batteries pour tous les outils. Il existe d’autres gammes possible bien sûr, mais l’ensemble que je vous proposes est cohérent.

  • L’outil de départ, c’est bien sûr la tronçonneuse. Auquel il faut rajouter les outils de protection, casque (du coup la protection des oreilles est inutile avec les outils électriques, mais, il vaut mieux avoir un casque qui fait les deux si jamais vous manipulez des outils thermiques), gants et combinaison anti-coupure et l’affûteuse ainsi qu’une chaîne de remplacement et de l’huile.
  • Ensuite il faut de quoi accéder au bois, d’ou la débroussailleuse, et l’élagueuse qui permet de couper les branches et de prendre moins de risque quand on coupe le tronc.  La débroussailleuse peut faire aussi coupe bordure, mais attention à prendre des fils biodégradable sinon (et c’est un vrai problème) vous allez saturer votre forêt ou jardin de micro-plastiques (déjà qu’il y en a suffisamment qui tombent du ciel !)
  • Pour les plus experts il est possible de se faire un kit « escalade » à base de matériel de spéléo pour monter dans les arbres et les ébrancher de haut en bas. Avec un baudrier, deux pieds ascenseur gauche et droit (bien plus pratique que la méthode classique avec un pied et une main). Attention à ne pas prendre de la corde d’escalade qui est plus élastique que celle de spéléo mais qui n’est pas faite pour monter du coup.
  • Il faut un palan (ou tirefort) pour tirer l’arbre dans le bon sens si éventuellement sa chute pose problème ou alors un treuil électrique pour débarder. A l’époque j’avais pris un Timbertech dont je suis content.
  • La brouette électrique pour ramener le bois. On est d’accord ça ne remplace pas un bon vieux chenillard thermique, mais l’idée ici c’est qu’une fois qu’on a des batteries (certes elles ont une durée de vie limitée, mais la technologie s’améliore) on est autonome, plus besoin de dépendre du pétrole. Je dois préciser que la brouette greenwork tools à un gros défaut, elle n’a pas de frein. Pour ma part, je ne l’ai pas achetée car je me suis bricolé ma propre brouette électrique à base d’une roue électrique achetée sur AliExpress qui fonctionne en 48V avec la batterie de mon vélo électrique. Il y a d’autres brouettes sur amazon que je trouve meilleures, je ferais une revue plus tard. Mais la brouette que je vous proposes dans ce kit fonctionne avec les même batteries que les autres outils.
  • J’ai rajouté un fendoir électrique que personnellement je trouve très pratique car je n’ai pas d’endroit ou utiliser un merlin classique (qui fait très bien le job sinon). 

(si vous n’avez pas accès au widget, voici l’équivalent en liste amazon)

Kit autonomie off-grid solo

Je vous proposes de découvrir mon kit autonomie solo. Il est constitué des outils les plus polyvalents possible afin d’assurer les besoins de base : eau, électricité, communication, défense, chauffage. Vous pouvez l’utilisez de façon nomade, ou bien comme complément/assurance en appartement.

Les outils phare du kit :

  • La jerrican Lifesaver, outil de collecte, purification et mise sous pression de l’eau tout en un.
  • La mini centrale électrique Poweroak qui peut être chargée au solaire ou autre, et qui fournit du 220V ou de l’USB en sortie. Pour les panneaux solaires il y a un modèle 100W qui est intéressant mais je préfère le 200W pliant, parce que dans la pratique si l’ensoleillement ou l’angle du panneaux n’est pas parfait vous n’aurez pas les 200W plutôt 100 …
  • Le hamac-tente-moustiquaire Lawson
  • Le réchaud Biolite campstove 2 et le kettelpot pour chauffer la nourriture ou l’eau et qui dispose d’un petit générateur USB d’appoint (pour recharger les lampes ou talkie quand il n’y a pas de soleil)
  • Le Letherman Surge, multitool qui a fait ses preuves.

Plus un EDC (Every day carry) :

Plus quelques accessoires et surprises que je vous laisse découvrir.

(l’affichage du widget ne passe pas bien firefox, à défaut voici ma liste amazon équivalente)

Retex en tant que CTO d’une startup

Article posté initialement sur le forum pragmatic entrepreneur. (La rédaction a été améliorée)

J’ai été CTO pour une startup Web. Du point de vue technique c’est très enrichissant : on est seul chef à bord, il faut tout gérer donc on touche à tous les domaines du web au lieu d’être confiné à une certaine expertise.

Pour ma part, j’en ai profité pour enfin pouvoir travailler proprement avec un process qualité que je n’avais jamais pu mettre en place dans les sociétés de services (tests automatisés, politique de déploiement propre, backups, etc…).
Je ne jette pas la pierre sur les SSII, elles ne font pas le même job : souvent ce sont des sites jetables, à bas coûts, alors que dans mon cas je savais que le site allait de voir vivre et évoluer plusieurs années.

D’autre part, alors qu’en SSII je devenais de plus en plus  » spécialiste de la spécialité », c’est à dire confiné à un domaine d’expertise de plus en plus restreint, en tant que CTO j’ai pu m’occuper de tous les aspects d’un site web (SEO, backup, perf, versionning, deploiment, monitoring, marketing, architecture, hébergement, ABtesting, sécurité, etc…). En plus j’ai eu la chance de participer à une ICO (sur la blockchain ethereum) qui a réussie.

Mais …
C’est donc un boulot exigeant, il faut être sur tous les fronts, et bien souvent, à n’importe quelle heure, notamment pour gérer les urgences. Ensuite on est mal payé, c’est un fait. Si la startup décolle c’est intéressant c’est sûr, mais il y a beaucoup d’échecs et contrairement aux investisseurs qui répartissent le risque sur plusieurs entreprises, le CTO en général n’en gère qu’une. Si ça « plante », il a gagné de l’expérience, mais c’est à peu près tout.

Après, de l’expérience justement, je pense qu’il faut quand même beaucoup en préalable pour gérer une startup en tant que CTO : il faut être capable de faire les bons choix, ça va de soi, mais ce n’est pas tout, il faut être capable de les expliquer. Parce que souvent, ce qui se passe c’est que les bons choix coûtent plus cher à court terme, mais moins cher à long terme et une startup c’est parfois de la survie au jour le jour. Il faut savoir gérer les demandes du “patron” qui n’est pas toujours au fait des pratiques et de la culture du web, et il faut gérer les autres développeurs, plus ou moins compétents, plus ou moins motivés, dans un environnement ultra-compétitif.

Les outils professionnel open-source de collaboration (pour entreprise ou association)

Voici une liste des outils que j’utilise dans mon activité professionnelle ou associative et dont je suis pleinement satisfait. Tout est open-source. Leur installation peut donc se faire « gratuitement » si vous avez les compétences. Et on peut les utiliser en SaaS.

Mais avant de vous donner « ma » liste, il me faut parler du « pourquoi » utiliser ces outils. C’est une question de philosophie et de politique plus que de technique, parce que, c’est vrai, il faut le dire, les outils « classiques » font le job.

D’abord, il y a la propriétés des données. Pour une entreprise, il me semble important que ces dernières restent en son sein et n’aillent pas se balader chez d’autres. Pour une question de risques, mais aussi d’espionnage industriel (oui ça existe).

Ensuite il y a le fait de « partager », ne serait-ce que des remontées de bugs avec les communautés open-source.

L’inconvénient c’est qu’il y a un surcroît de travail, c’est vrai. Il faut installer ces outils, les mettre à jour, faire des backups, etc… Et on n’a pas toujours le temps de s’en occuper, et d’ailleurs, on ne sait pas toujours quels outils en valent le coup, alors, on fait comme les voisins !

  • Gitlab : github est très bien pour se donner une visibilité publique. J’utilise gitlab pour les projets privés. L’avantage c’est d’avoir une plus grande intégration avec les outils du système d’information de l’entreprise. Les outils de workflow, l’intégration continue, la gestion des merge request et des issues avec le dashboard étaient utilisés par mon équipe quotidiennement et nous rendaient de vrais services.
  • Mattermost : outil que j’ai découvert récemment, il remplace avantageusement slack. Les conversations vidéos en 1to1 sont possible via zoom (qui n’est pas open-source) d’entrée de jeu, mais il semble possible de configurer un WebRTC pour le remplacer (je n’ai pas encore eu le temps de le faire). Les webhook (ingoing et outgoing sont bien présent) et permettent d’avoir des alertes comme avec slack. Le gros point fort de mattermost, ce sont les Team qui sont très bien intégrées à l’outil et plus conviviales que dans slack.
  • Drupal / WordPress : on ne les présentes plus. Pour les projets pro, Drupal permet de construire toutes sortes de sites d’envergure. Pour les blogs perso ou associatifs, wordpress est le meilleur.
  • TICK : c’est un acronyme pour une suite d’outils de monitoring : Telegram (un démon qui récolte et envoies les données), InfluxDB (une base de donnée de série temporelles), Chronograf (un outil de visualisation de séries temporelles), Kapacitor (un outil de levée d’alertes en fonction de seuil). Cet outil permet de monitorer un ensemble de serveurs de manière fine et permet de détecter des problèmes en amont (comme par exemple, un disque dur qui se remplit, ce qui peut provoquer des erreurs très bizarres qu’on ne comprends pas de premier abord), ou des problèmes de performance. Je l’avais préféré aux outils traditionnels de monitoring comme Munin ou Nagios (ou tant d’autres) pour sa simplicité et sa capacité à mettre en graphes.
  • Piwik/Matomo : le google analytics open-source, qui disposes des fonctionnalités de base pour analyser le trafic mais aussi d’outils plus avancés comme les funnels et bien d’autres dans ses plugins.
  • Docker : alors que vagrant est très bon pour monter des machines virtuelles, docker est tout de même plus puissant avec ses images et conteneurs, la possibilité de versionner facilement ses environnements. Il est aussi moins gourmand et on peut donc l’utiliser pour déployer simplement des environnement de dev « iso » d’un serveur à l’autre.
  • Ansible : bien que n’ayant encore que peu d’expérience avec Ansible, je le rajoute à ma boite à outil pour gérer les déploiements de manière industrialisée (les classiques : site de dev, préprod, prod notamment).
  • Loomio : outil de prise de décision collective, qui permet de voter sur des sujets et qui est utilisé par certains mouvements politiques. J’y vois deux gros intérêts. D’abord le vote de base dispose de quatre boutons « favorable, abstention,défavorable,contre ». Je trouve ça très malin d’avoir introduit la nuance entre défavorable/contre. D’autre part il y a aussi un outil de prise de RDV un peu comme Doodle.
  • KeepassX : indispensable pour gérer ses mots de passe perso ou pro sans avoir à faire tourner 2 ou 3 mot de passes qu’on a mémorisé. De plus, couplé avec Nextcloud, il permet de partager un fichier de mot de passes admin et évite les trous de sécurités classique des mots de passes qui transitent par des canaux moins sécurisés.
  • Behat : j’exagère à peine en disant que Behat m’a sauvé la vie. C’est un outil de test de sites web automatisé (par script ecrits en « langage naturel » ou presque). Je l’ai utilisé principalement pour des sites Drupal et je n’ai pas creusé pour savoir s’il existe en version nodejs ou pour WordPress. Mais, un outil de test sémantique me semble indispensable pour mener à bien un projet web sur le long terme et avoir confiance dans son produit. De plus, Behat permet d’avoir des specs « utiles » et à jour puisqu’elles servent à lancer les tests. Behat s’insère très bien dans le workflow d’intégration continue de gitlab.
  • Nextcloud : il arrive en dernier mais c’est un poids lourd. Au départ, je ne l’ai installé qu’en tant que remplaçant de Dropbox. Mais il est tellement riche de fonctionnalités qu’on peut lui trouver bien plus d’utilités. Par exemple, la première extension que j’ai rajoutée est « Collabora », une version de google-docs issue de Libre-office.
  • Pencil : pour créer les wireframes, les mockups, les maquettes de votre site avant de faire appel à un graphiste.
  • Pour les performances et la scalabilité : xdebug, locust.io, xhprof, xhgui
  • backstopjs : pour les tests de régression visuel

Drupal 7 et ethereum, un hello world avec web3.js et parity : acheter un token

A supposer que vous soyez déjà enregistré en tant que user drupal reconnu sur la blockchain et que vous ayez déployé un contrat Token ERC20, nous allons voir comment faire pour :

  • afficher votre solde de token
  • acheter un token avec vos ethereums
  • modifier votre solde dès qu’ils change
  • valider la transaction automatiquement (2 méthodes)

Le code complet (et testé) est disponible sur github. Je ne reviens pas sur les principes de base : Drupal.settings, connexion à la blockchain, création de l’instance du contract dans JS. On va se concentrer sur les manipulations que l’on fait sur le contrat, en javascript, via web3.js.

Afficher votre solde en temps réel

A supposer que vous ayez initialisé votre contrat, afficher le solde en token de votre compte se fait avec un simple .call :

token_contract.methods.balanceOf(clientAddress).call().then(function(result){$("#client-token").html(result);});

Mais cet affichage sera fait une seule fois au chargement de la page. Hors, la blockchain peut enregistrer des transactions depuis n’importe quel client. Le solde peut donc changer à tout moment. Comment faire pour que votre soit mise à jour en temps réel le cas échéant ? Si votre smartcontract l’a prévu, vous pouvez utiliser les évènements à cet effet :

event Transfer(address indexed from, address indexed to, uint256 value);

    function _transfer(address _from, address _to, uint _value) internal {
        // Prevent transfer to 0x0 address. Use burn() instead
        require(_to != 0x0);
        // Check if the sender has enough
        require(balanceOf[_from] >= _value);
        // Check for overflows
        require(balanceOf[_to] + _value > balanceOf[_to]);
        // Save this for an assertion in the future
        uint previousBalances = balanceOf[_from] + balanceOf[_to];
        // Subtract from the sender
        balanceOf[_from] -= _value;
        // Add the same to the recipient
        balanceOf[_to] += _value;
        Transfer(_from, _to, _value);
        // Asserts are used to use static analysis to find bugs in your code. They should never fail
        assert(balanceOf[_from] + balanceOf[_to] == previousBalances);
}

Le smartcontract définit un évènement Transfer qui est appelé dans la fonction interne _transfer. Il déclenche un appel qui peut être intercepté coté javascript à l’aide du code suivant :

token_contract.events.Transfer().on('data', function(event){
  token_contract.methods.balanceOf(clientAddress).call().then(function(result){$("#client-token").html(result);});
});

On retrouve le même code d’affichage du solde, mais en tant résultat d’une promise d’un .events.Transfer().on('data', {}) . Sauf que si vous vous arrêtez la, vous allez avoir un petit problème. Le HttpProvider que l’on utilises pour web3 ne supporte pas les évènements. Il faut utiliser le WebsocketProvider :

window.web3 = new Web3(new Web3.providers.WebsocketProvider(fallback));

Et pour que ça fonctionne on doit saisir une url du style : ws://localhost:8546. Le port n’est plus 8545 mais 8546 et le http transformé en ws. A partir de ce moment la, votre appel d’évènement fonctionnera et le solde sera mis à jour en temps réel.

Acheter des tokens

L’achat de Token doit être prévu dans votre smartcontract. C’est une simple fonction qui augmente votre solde à une nuance près, elle est « payable » :

    function buy() payable public {
        uint amount = (msg.value / buyPrice) * unit;      // calculates the amount
        _transfer(this, msg.sender, amount);              // makes the transfers
}

L’appel se fait donc simplement par un .send :

token_contract.methods.buy().send({from:clientAddress, value:web3.utils.toWei(0.001, "ether")})

Notez que dans le cas présent (un token ERC20 donc) le solde n’est pas simplement augmenté, mais un transfert est réalisé depuis le contrat lui même vers le user. C’est la signification du _transfer(this, Ce qui peut sembler étrange au premier abord, mais qui permet en fait de fixer le nombre de Token à la création (selon la même astuce déflationniste utilisée par bitcoin qui consiste à ne créer que 21 millions de bitcoin au maxium). En fonction du prix d’achat du token et du taux de conversion, vos ethers seront convertis en token.

Valider la transaction via parity

Avec le code tel qu’il est présenté précédemment, l’utilisateur devra obligatoirement basculer sur son wallet (Mist, Partiy, Jaxx, MetaMask ou autre) pour valider la transaction en saisissant son mot de passe. Pour un utilisateur expérimenté habitué à ethereum c’est acceptable, mais pour le grand public, il y a un risque que l’utilisateur attende sans comprendre qu’il doit valider sa transaction « de l’autre coté ». Mais nous pouvons l’aider. Il y a un 2ème cas ou la validation de transaction peut-être intéressante : pour les développeurs. C’est en effet pénible de devoir aller valider à chaque fois qu’on teste. Enfin, c’est carrément rédhibitoire pour les tests automatisés. Dans tous ces cas, il peut être utile de savoir comment faire.

La première méthode consiste à appeler parity nous même pour lui dire de valider la dernière transaction de son pipe. Ce n’est pas la méthode la plus sûre dans la mesure ou quelqu’un d’autre pourrait avoir rajouté une transaction dans l’intervalle. Mais ça peut suffire (notamment pour les développeurs).

Nous allons utiliser l’API JsonRPC de parity, qui s’utilise comme un appel AJAX. Cela se fait en 2 étapes, d’abord signer_requestsToConfirm pour récupérer les transactions en attente de signature, puis, nous allons demander à l’utilisateur son mot de passe et l’envoyer à parity avec un signer_confirmRequest.  Ce qui nous donne le code suivant :

        autoSign = function() {
          $.ajax({
            type:"POST",  url: fallback, Accept : "application/json", contentType: "application/json",  dataType: "json",
            data: JSON.stringify({"method":"signer_requestsToConfirm","params":[],"id":1,"jsonrpc":"2.0"}),
            success: function(result) { 
              if (result.result == []) alter('Could not sign');
              if (result.result[0] == undefined) alter('Could not sign');
              id = result.result[0].id;
              pass = $('#eth-password').val();
              $.ajax({
                type:"POST", url: fallback, Accept : "application/json", contentType: "application/json", dataType: "json",
                data: JSON.stringify({"method":"signer_confirmRequest","params":[id, {}, pass],"id":1,"jsonrpc":"2.0"}),
                success: function(result) { alert('transaction validated automatically'); }
              });
            }
          });
}

Mais ce n’est pas une solution entièrement satisfaisante dans la mesure ou : on passe par parity. Que faire si on souhaite utiliser geth ? Et s’il y a d’autres transactions dans le pipe ? Sans parler du fait qu’il est difficile de savoir « quand » faire l’appel vers parity (il faut lui laisser le temps de créer sa transaction). Vous aurez remarqué dans le code que l’appel se fait après un delai :

            setTimeout(function() {autoSign();}, 1000);

Nous allons maintenant voir comment signer la transaction proprement avec eth3. Mais c’est un peu plus compliqué (et surtout non documenté à l’heure ou j’écris).

Valider la transaction avec web3

Sans plus tarder voici le code « propre » d’un appel de transaction signé dans web3 :

        autoSignWeb3 = function (pass, onreceipt) {
          var walletContractAddress = Drupal.settings.blockchain.token_deployed_contract_address_fallback;
          var privateKey = new buffer.Buffer(pass, 'hex');
          var fromAccount = clientAddress;
          var signature = _.find(JSON.parse(Drupal.settings.blockchain.token_deployed_contract_ABI), { name: 'buy' });
          var payloadData = web3.eth.abi.encodeFunctionCall(signature, []);
          gasPrice = web3.eth.gasPrice;
          gasPriceHex = web3.utils.toHex(gasPrice);
          gasLimitHex = web3.utils.toHex(300000);
          web3.eth.getTransactionCount(fromAccount).then((nonce) => {
            nonceHex = web3.utils.toHex(nonce);
            var rawTx = {
              nonce: nonceHex,
              gasPrice: gasPriceHex,
              gasLimit: gasLimitHex,
              to: walletContractAddress,
              from: fromAccount,
              value: web3.utils.toHex(web3.utils.toWei(0.001, "ether")),
              data: payloadData
              };
            var tx = new ethereumjs.Tx(rawTx);
            tx.sign(privateKey);
            var serializedTx = tx.serialize();
            web3.eth.sendSignedTransaction('0x' + serializedTx.toString('hex')).then( () =>{ onreceipt(); return null; } );
            return null;
          });
}

Si vous regardez la documentation de web3, vous trouverez facilement cette fonction web3.eth.sendSignedTransaction qui permet d’envoyer des transactions signées. Mais le problème c’est qu’on doit envoyer une chaine représentant la transaction. Il faut donc construire cette chaine. On est loin du .methods.xxx.send() plutôt naturel. Construire une sorte de code hexadécimal pour faire appel … ce n’est pas si simple, surtout que les exemples sur le net concernent des versions différentes ou plus anciennes de web3.js.

Pour y parvenir je me suis inspiré du code trouvé ici. Sauf que sendRawTransaction est remplacé par sendSignedTransaction, mais surtout :

var solidityFunction = new SolidityFunction('', _.find(ABI, { name: 'sendCoin' }), '');
var payloadData = solidityFunction.toPayload([toAccount, 3]).data;

est remplacé par

 var payloadData = web3.eth.abi.encodeFunctionCall(signature, [toAccount, 1]);

C’est cette partie qui fût la plus compliquée à trouver dans le dédalle du net. On doit faire appel à 3 libraires js externes :

  • ehtereumjs-tx qui sert à sérialiser la transaction.
  • buffer qui sert à envoyer la clé à la transaction
  • lodash qui sert à récupérer la signature de la méthode qu’on veut appeler dans l’ABI

De plus, l’utilisateur ne doit pas saisir le mot de passe de son wallet parity mais sa clé privée. On pourrait tout à fait crypter sa clé à l’aide d’un mot de passe et ne lui demander que ce mot de passe (au final, c’est ce que fait parity), mais ça dépasse le cadre de cet article.

Drupal 7 et ethereum, un hello world avec web3.js et parity : s’enregistrer sur la blockchain

Cet article suppose que vous connaissez déjà la blockchain (BC). C’est une sorte de base de donnée (coûteuse) infalsifiable, avec, dans le cas d’ethereum (ETH) la possibilité d’exécuter des bouts de code certifiés (dans un langage de programmation proche du javascript : solidity). Si ces notions ne vous sont pas familières, passez votre chemin.

La BC est une technologie en pleine évolution (et en plein boom). Il y aurait beaucoup à dire, mais dans cet article, on va se limiter à ropsten, parity, web3.js 1.0 et … drupal (version 7 – oui c’est un peu vieillot) et comment coder un « hello world » en Drupal pour se connecter à la BC.

Nous allons réaliser 2 choses :

  • connexion d’un user drupal avec un compte de la BC
  • achat d’un token ERC20, avec validation automatique de la transaction (ce qui permet de se passer d’un wallet)

Dans ce premier article, on va déjà s’intéresser au premier cas.

Environnement de développement

A supposer que vous ayez un site Drupal quelconque. Par exemple, un que vous avez installé à l’aide d’ansible. Il va vous falloir en plus le module user_hash, et un champ « ethereum_address » de type string en plus sur votre profil utilisateur. Pour faire fonctionner la BC, pour les développeurs, il est conseillé d’utiliser parity (1.8.3 à l’heure ou j’écris). Une fois installé, vous lancez parity comme ceci :
parity ui --chain=dev --unsafe-expose --jsonrpc-apis=all
Cette ligne de commande permet d’avoir un parity « de dev » qui tourne sans aucune restriction. Quand on démarre et qu’on est dans une VM, j’estime que ce n’est pas encore l’heure de ses pré-occuper de la sécurité. Chaque chose en son temps. La, ce qu’on veut c’est voir la bête tourner.

Si vous souhaitez accéder à l’interface en ligne de parity (et je vous le conseille) : http://192.168.50.5:8180/#/accounts/

192.168.50.5 est l’IP fixe privée que j’ai donné à la VM vagrant (sinon, ça sera probablement sur localhost) :
config.vm.network "private_network", ip: "192.168.50.5
Vous devez obtenir quelque chose comme ceci (ce n’est pas un tuto parity, je n’irais donc pas plus loin à ce sujet) :

A partir de la, il vous faudra créer un compte pour chaque user drupal que vous souhaitez connecter à la BC.

Cette instance de parity fonctionne avec une blockchain de dev, locale, légère, rapide, mais une fois que votre application fonctionnera, il vous faudra basculer sur une version publique de test d’ethereum: par exemple ropsten. L’avantage de parity c’est qu’il le permet très simplement, et qu’il fait aussi office de wallet (porte-feuille ethereum) et aussi il dispose d’outils pour les développeurs (notamment pour les contrats). Notez (mais ce n’est pas le sujet de cet article) que Mist (un autre wallet ethereum) dispose d’une debugger de smart-contract assez bluffant (si jamais vous avez besoin d’en arriver la). Mais en dehors de ce cas, parity fait tout à fait l’affaire.

Préparation des données

[Attention, ce n’est pas un tuto drupal, donc je passe rapidement sur les étapes principales du code Drupal]

On peut communiquer avec le BC de différentes manières possibles, mais le plus simple et le plus répandu c’est d’utiliser la librairie web3.js en javascript, pour se connecter au noeud parity. On pourrait se connecter au noeud en PHP (à l’aide d’ethereum-php mais ce n’est pas une librairie officielle et le coté asynchrone des appels à la BC sont plus facile à gérer en JS).

Récupérez une web3.min.js. Qu’on va ensuite injecter avec un :

drupal_add_js(drupal_get_path('module', 'hellothereum') . '/js/web3.min.js', array('scope' => 'footer'));

De l’autre coté, il va nous falloir un champ pour accueillir l’adresse ethereum du user (à la rigueur on pourrait aussi se contenter de la rechercher le hash du user dans la blockchain pour récupérer son adresse. Il faudrait réfléchir aux conséquences en terme de performance et de sécurité des 2 choix, mais ça dépasse le cadre de ce simple article qui vise à découvrir les fonctions de base).

Cette partie se fait avec un field_create_field et un field_create_instance dans le hook_enable :

  if (!field_info_field('field_ethaddress')) {
    $field = array(
        'field_name' => 'field_ethaddress', 
        'type' => 'text', 
    );
    field_create_field($field);

    // Create the instance on the bundle.
    $instance = array(
        'field_name' => 'field_ethaddress', 
        'entity_type' => 'user', 
        'label' => 'Ethereum address', 
        'bundle' => 'user', 
        'settings' => array(
           // Here you inform either or not you want this field showing up on the registration form.
            'user_register_form' => 1,
        ),
        'widget' => array(
            'type' => 'textfield',
            'weight' => '1',
        ), 
    );
    field_create_instance($instance);
}

Avec le module user_hash, et le champ ethaddress, on est équipé pour aller taquiner la blockchain. Il ne nous reste plus qu’à envoyer les informations au javascript qui va passer par Web3 pour appeler les smartcontract. Les adresses des smartcontract et leur ABI sont stockés dans la table variable et envoyées au JS :

    drupal_add_js(array(
      'ethereum_user' => array(
        'contract' => array(
          'address' => variable_get('ethereum_user_register_drupal_deployed_contract_address'),
          'abi' => variable_get('ethereum_user_register_drupal_deployed_contract_abi'),
        ),
        'fallback_node' => variable_get('ethereum_user_register_drupal_fallback_node'),
        'token' => variable_get('ethereum_user_registry_list_token'),
        'user' => array(
          'hash' => $this_user->hash,
          'address' => $this_user_ethereum_address,
        ),
      ),
    ), 'setting');

Appel des smart-contracts en JS

On récupère d’abord toutes les infos nécessaires envoyées par Drupal via Drupal.settings :

        window.web3 = new Web3(new Web3.providers.HttpProvider(Drupal.settings.ethereum_user.fallback_node));
        var user_address = Drupal.settings.ethereum_user.user.address.toLowerCase();
        var contract_abi = JSON.parse(Drupal.settings.ethereum_user.contract.abi);
        var contract_address = Drupal.settings.ethereum_user.contract.address;
        var contract = new web3.eth.Contract(contract_abi, contract_address);
        var user_hash = Drupal.settings.ethereum_user.user.hash;

A partir de la, on va pouvoir enfin faire notre premier appel de smart-contract. Attention, c’est du code asynchrone qui utilises des « promises » ou des « callbacks » (au choix). On n’écrit donc pas du code séquentiel (comme c’était le cas avec les premières versions de web3.js). Dans les versions précédentes de web3.js on faisait un appel de méthode classique. Cette fois il faut rajouter .methods avant l’appel et .call après. Ce qui donne :

contract.methods.validateUserByHash(user_hash).call({from: user_address}, function (error, result) {

Voyons le code du contrat correspondant :

  function validateUserByHash (bytes32 drupalUserHash) constant returns (address result){
      return _accounts[drupalUserHash];
}

Il est très simple. Le contrat dispose d’une table de correspondance, comme un tableau associatif en php, et il se contente de renvoyer une entrée à l’indice indiqué, si elle existe.

Comme vous le voyez, le contrat ne définit qu’un seul paramètre qu’on retrouve dans le .validateUserByHash(user_hash), le reste de l’appel, contient les paramètres « génériques » d’un appel de contrat : .call({from: user_address}, function (error, result) { qui est le user qui fait l’appel de contrat, et quelle est la callback à déclencher en retour. Dans le cas des transactions payantes on pourrait aussi ficher un prix.

Le traitement du résultat de l’appel se fait donc dans la fonction de callback. S’il n’y a pas eu d’erreur, c’est la qu’on peut vérifier si l’utilisateur est déjà enregistré et, si c’est pas le cas, lui proposer une transaction d’enregistrement :

contract.methods.newUser(user_hash).send({from: user_address})

Cette fois-ci c’est un .send à la place du .call, j’y reviens un peu plus loin. Voici le code solidity correspondant :

  function newUser(bytes32 drupalUserHash) public {

    if (_accounts[drupalUserHash] == msg.sender) {
      // Hash allready registered to address.
      accountCreated(msg.sender, drupalUserHash, 4);
    }
    else if (_accounts[drupalUserHash] > 0) {
      // Hash allready registered to different address.
      accountCreated(msg.sender, drupalUserHash, 3);
    }
     else if (drupalUserHash.length > 32) {
      // Hash too long
      accountCreated(msg.sender, drupalUserHash, 2);
    }
    else if (_registrationDisabled){
      // Registry is disabled because a newer version is available
      accountCreated(msg.sender, drupalUserHash, 1);
    }
    else {
      _accounts[drupalUserHash] = msg.sender;
      accountCreated(msg.sender, drupalUserHash, 0);
    }
}

Le code est très simple en soi si on enlève les vérifications qui sécurisent le contrat : _accounts[drupalUserHash] = msg.sender;. La dernière ligne est un évènement, ce sera traité dans les prochains articles.

Cette fois, par contre, on va utiliser les « promises » pour réagir à la transaction plutôt qu’une callback. Dans ce cas précis les promisses permettent d’avoir une action à différents moments. Notez une différence majeure par rapport au .call précédent : elle doit être validée par l’utilisateur, dans son wallet, puis être ensuite « minée », c’est à dire confirmée dans la blockchain. Typiquement, on est dans de l’asynchrone la. Notre javascript, ni notre site, ne s’arrêtent de vivre parce que la blockchain fait son boulot de son coté.

              .on('transactionHash', function (transactionHash) {
                $('#ethereum_user_registry_sign').html('<p>Please wait between 10 seconds and a few minutes for the transaction to be mined on the Ethereum network. You can reload this page at any time to see if the transaction is confirmed. Or you can <a href="https://etherscan.io/tx/' + transactionHash + '" target="_blank">see the transaction status in live</a>.</p>');
              })
              .on('error', function (error) {
                // 0 is "success error" in RegisterDrupal.sol
                if (error != 0) {
                  console.error;
                }
              })
              .on('confirmation', function (confirmationNumber, receipt) {
                // Should be 0 because there's no block after this transaction yet.
                console.log('Number of confirmation blocks: ' + confirmationNumber);
               })

On peut réagir à plusieurs évènements. TransactionHash : c’est quand la transaction est crée, c’est à dire, quand l’utilisateur valide la transaction dans son wallet. Sinon, on déboule sur une erreur. Si la transaction est validée, en principe, elle va finir en confirmation, sauf s’il y a une error déclenchée dans le smart-contract. Si votre smartcontract est bien fait, il va vous remonter une erreur explicite. Sinon … c’est la qu’on commence à pleurer ! Mais il y a une solution.

Si jamais vous être coincés et que ne comprenez pas pourquoi votre smartcontract ne renvoies pas le résultat attendu, vous pouvez lancer Mist qui contient un debugger de smart-contract, tout à fait bluffant. Ce n’est pas le sujet de cet article, je ne m’étendrais pas, mais sachez simplement qu’il permet de dérouler votre code comme film, y compris de faire du rewind et qu’il est vraiment très bien fait. C’est le même debugger que « Remix IDE« , mais qui tourne sur votre BC locale.

Voila, vous avez les bases. Il nous restera à voir dans les prochains articles : les transactions payantes, les évènements, l’auto-signature, pour faire un premier tout d’horizon plus complet des possibilités principales de la blockchain.