Programmer une Dapp — day 4

Premier Smart-Contract

GrandSchtroumpf
5 min readJun 3, 2018

Quatrième meetup à Lyon sur la programmation de Dapp avec Ethereum. Cette semaine nous découvrons comment créer un smart-contract simple sur Ethereum en Solidity avec Remix.

Rappel

Avant de commencer voici un petit rappel sur comment déployer un contrat sur Ethereum en principe :

Rappel — Comment déployer un smart-contract

Tout d’abord on écrit un smart-contract, il existe plusieurs langage : Solidity, Viper, Serpent, LLL, Flint (et sûrement d’autres). Le code est ensuite compilé grâce à un compilateur, dans le cas de solidity on utilise solc. Cela nous permet de récupérer le bytecode du contrat. Le bytecode est ensuite encapsulé dans une transaction. La transaction est envoyée sur le réseau Ethereum via la méthode RPC send_transaction. Le contrat est ensuite traité par une Machine Virtuelle Ethereum (EVM).

Créer un smart-contract consiste donc à écrire le code, le compiler et déployer le bytecode.

Remix

Remix est un IDE en ligne pour écrire, compiler, tester et déployer des smart-contract en Solidity. Quand vous ouvrez Remix pour la première fois vous pouvez voir un premier smart-contract Ballot qui permet de découvrir le langage.

Remix et le contrat Ballot.sol

Dans notre cas nous n’allons pas utiliser ce contrat, et allons en créer un beaucoup plus simple. Notre contrat s’appelle MessageSender et a pour but d’associer à une adresse Ethereum un message. Pour cela supprimons le contrat Ballot.sol et créons un contract MessageSender.sol.

Par convention le nom du fichier correspond au nom du contrat. Et le nom du contrat est en PascalCase.

Créer un nouveau contrat

Solidity

Contrat Simple

Nous allons créer un contrat simple qui associe un message à une adresse Ethereum :

Un contrat solidity commence toujours par définir la version utilisée. C’est une indication pour le compilateur Solidity solc.

pragma solidity ^0.4.23;

Ensuite nous pouvons définir le contrat. On peut voir un contrat comme une classe de n’importe quel langage orienté object :

contract MessageSender {}

Pour ce contract il nous faut deux méthodes :

  • sendMessage qui défini un message pour une adresse Ethereum (écriture)
  • messages qui permet de lire le message associé à une adresse donnée (lecture).

Commençons par messages , il s’agit d’un mapping qui associe à une adresse un message (pour l’instant on ne mettra qu’une chaine de caractères).

mapping(address => string) public messages;

Ce mapping prend en entrée une valeur de type address et retourne une chaine de caractère. Notez que nous définissons messages en public. C’est parce que nous voulons que notre Dapp puisse interroger cette méthode.

Définir une méthode en public n’a rien à voir avec la sécurité du contrat. Cela permet juste d’ajouter la méthode dans l’ABI (Abstract Binary Interface) qui décrit les contrats pour les Dapps.

A présent écrivons la méthode sendMessage :

function sendMessage(address to, string content) public {
messages[to] = content;
}

C’est une méthode très simple qui associe à une adresse un message.

Il s’agit d’une méthode en écriture car nous modifions une valeur du storage (c’est-à-dire le state de Ethereum). Exécuter cette méthode implique de créer une transaction et donc payer une taxe de transaction aux mineurs.

Compiler

Pour compiler il suffit d’appuyer sur “start to compile”. Normalement vous devirez avoir un message en vert avec le nom de votre contrat qui indique que le contrat est bien compilé.

Compile

Vous pouvez voir les détails de compilation dans “details”. Vous y trouverez notamment le bytecode et l’ABI.

Détails de compilation

Déployer

A présent nous pouvons déployer le bytecode. Remix possède une EVM JavaScript locale qui permet de tester nos contrats sans avoir à les déployer sur un chaine Ethereum (Mainnet, Ropsten, Rinkeby ou Kovan). C’est très pratique parce que nous n’avons pas besoin d’avoir d’Ethers pour tester, ni d’attendre que les transactions soient validées.

Pour cela aller dans “run” en haut à droite puis selectionner l’environnement “Javascript VM” (sélectionné par défaut normalement). Vous pouvez voir que l’EVM vous donne accès à 5 comptes avec chacun 100Ethers.

JavaScript EVM

Vous pouvez déployer le contrat en cliquant sur “deploy”. Vous pouvez observer la transaction dans la fenêtre de log en bas de l’écran. L’instance de votre contrat est en bas de la sidebar de droite avec son adresse et ses méthodes. Les méthodes en rouges sont en écriture et les méthodes en bleus sont en lecture.

Notez que le compte qui a déployé le contrat n’a plus 100Ethers parce que nous avons payé du gas pour créer notre transaction.

Contrat déployé

Tester le contrat

Il est tant de tester notre contrat. Il suffit d’entrer les valeurs de notre méthode sendMessage dans les champs de texte. Pour faciliter l’écriture vous pouvez cliquer sur la flèche vers le bas pour découvrir les différents inputs:

  • to : Je mets l’adresse de mon deuxième compte. Pour cela je peux cliquer sur l’icone “copier” à droite du champ “accounts”.
  • content : Le traditionnel “Hello World”.

Cliquez que “sendMessage” (ou “transact”). Vous voyez la transaction apparaitre dans la console de logs. Vous pouvez maintenant entrer la même adresse que vous avez utilisée pour to dans l’input de la méthode messages et cliquer sur le bouton. Remix vous affiche “Hello World” comme prévu.

Tester notre contrat

Améliorer le contrat

Maintenant que nous avons réussi à déployer et tester le contrat nous pouvons un peu l’améliorer. L’idée est d’ajouter l’information de qui a envoyé le message au lieu de juste stocker le contenu du message.

Pour cela nous créons une struct avec deux valeurs :

struct Message {
address from;
string content;
}

Puis nous modifions le mapping pour retourner un objet de type Message au lieu d’une chaine de caractères :

mapping(address => Message) public messages;

Enfin nous modifions notre méthode sendMessage pour ajouter l’expéditeur. Pour cela nous utilisons une variable globale msg qui donne accès notamment à l’adresse de l’expéditeur. Aussi nous castons nos informations dans une structure Message

function sendMessage(address to, string content) public {
messages[to] = Message(msg.sender, content);
}

Et voilà !

Vous n’avez plus qu’à compiler, déployer et tester !!

--

--

GrandSchtroumpf

I co-founded DappsNation, a Blockchain studio that build awesome decentralized applications. I also work at the Ethereum Foundation for the Remix project.