Fermer

juin 4, 2018

Génération de nombre aléatoire pour Ethereum –


Cet article a été créé en partenariat avec iOlite . Nous vous remercions de soutenir les partenaires qui rendent SitePoint possible.

Solidité est un langage relativement nouveau et comme aucun code n'est parfait, il contient des problèmes liés au code et à ce que vous voulez accomplir avec. Cet article vous guidera à travers les bonnes pratiques et les pièges lorsque vous utilisez un nombre aléatoire comme entrée pour votre contrat smart Ethereum

Solidity Random Number Generation

Solidité n'est pas capable de créer des nombres aléatoires. En fait, chaque algorithme de création de nombres aléatoires est pseudo-aléatoire – aucun langage n'est capable de créer des nombres complètement aléatoires. Le problème avec Solidity est que les algorithmes complexes coûtent trop cher, donc des solutions plus basiques sont utilisées. En outre, le code de Solidité devrait être déterministe, car il fonctionnera sur plusieurs nœuds. Nous avons besoin d'un algorithme capable de générer un nombre aléatoire une fois et de l'utiliser sur plusieurs nœuds. Des choses comme une heure d'horloge ne sont pas disponibles pour générer des nombres aléatoires, nous devons donc regarder d'autres options. En tant que développeur, vous devez être conscient de ce problème car un attaquant est capable de prédire le résultat dans certains cas spécifiques.

L'un des algorithmes les plus couramment utilisés est le «générateur linéaire congruentiel» (LCG). C'est l'un des algorithmes les plus anciens, rapide et facile à comprendre. LCG est une bonne option pour les systèmes embarqués car ils ont une quantité limitée de mémoire. Cependant, il n'est pas bien adapté pour les applications cryptographiquement sécurisées. Bien que cela soit toujours utilisé dans les contrats intelligents, un algorithme rapide est beaucoup moins cher à mettre en œuvre en termes de coûts de gaz.

L'algorithme lui-même exécute ces étapes:

  • Accepter l'entrée
  • Exécuter l'algorithme sur l'entrée
  • Prendre le module de sortie (diviser par le nombre maximum dans la gamme requise)
  • Sortie entre 0 et nombre maximum Dans la gamme dont vous avez besoin

Explorons les différentes façons de créer des nombres aléatoires à l'aide d'un exemple de contrat intelligent Lottery. Les utilisateurs peuvent rejoindre la Loterie en envoyant 0.1 Éther au contrat avec un nombre entier compris entre 0 et 250.

1. Block.timestamp & Block.difficulty

Un bloc block.timestamp est assigné par le mineur chaque fois qu'il confirme la transaction. Aucun joueur de notre contrat de loterie n'est en mesure de le contrôler. Jetons un coup d'oeil à ce morceau de code pour créer un nombre aléatoire.

 function random () private view renvoie (uint8) {
       return uint8 (uint256 (keccak256 (block.timestamp, block.difficulty))% 251);
   }

Trouvez le Gist ici .

Ce morceau de code permet d'abord de hacher un bloc d'horodatage et de difficulté. Ensuite, nous convertissons le hachage en entier et le divisons par 251 pour obtenir un nombre entier entre 0 et 250. Cependant, le problème avec ce morceau de code est que nous ne devrions pas faire confiance à un mineur pour choisir un gagnant.

2 . Entrée de loterie – données arbitraires

Nous avons besoin de plus de données arbitraires pour choisir notre gagnant. Nous pouvons utiliser les adresses des joueurs qui ont participé à notre contrat de loterie, mais nous devons le cacher aux autres joueurs car ils peuvent en abuser. Cacher cette information n'est pas possible car tout est enregistré sur la blockchain.

Les numéros soumis à notre contrat de loterie intelligente peuvent être utilisés. Les utilisateurs doivent hacher le nombre qu'ils choisissent avec leur adresse Ethereum. Cela nous donne un nombre assez aléatoire.

3. Autres mécanismes

3.1 Réveil Ethereum

Les développeurs doivent réfléchir à quand choisir un gagnant. Des choses comme l'heure d'horloge ne sont pas disponibles dans la machine virtuelle Ethereum, car le code fonctionnera sur plusieurs nœuds, à une heure différente. Cela rend encore plus difficile de choisir un gagnant. Une façon de le faire est en mettant en place une fonction dans votre contrat intelligent qui fermera la loterie et choisira un gagnant. Ce n'est pas aussi décentralisé que nous le voulons. Le propriétaire du contrat peut fermer la loterie lorsqu'il est sûr qu'un de ses amis gagnera. Nous voulons éviter ce genre de triche.

Une meilleure option est d'utiliser le Réveil Ethereum. C'est un service qui permet d'exécuter des transactions de planification plus tard sur la chaîne de blocs Ethereum. Ce service est totalement fiable, ce qui signifie que l'ensemble du service fonctionne comme un contrat intelligent. Fondamentalement, le réveil Ethereum utilise le numéro de bloc pour planifier les transactions. Attention, cela ne signifie pas que le contrat se réveille tout seul. Il repose sur les utilisateurs ayant un intérêt (récompense Ether) pour avoir appelé la fonction 'gagnant gagnant'. Bien sûr, si personne n'appelle votre fonction, votre loterie échouera.

3.2 Entrée de données aléatoires

Random.org fournit une API qui vous donne une source aléatoire de données via JSON. Un contrat intelligent Ethereum peut utiliser cette source de données pour alimenter un algorithme qui choisit un nombre aléatoire. Comme la sécurité est importante, il est possible d'utiliser la signature numérique. Les données aléatoires seront signées par Random.org. Vous pouvez vérifier l'intégrité des données afin de prouver qu'elles proviennent vraiment de Random.org et que les données n'ont pas été altérées.

RANDAO est un nouveau projet dans l'espace blockchain qui se concentre uniquement sur la fourniture de nombres aléatoires. Ils utilisent une combinaison d'oracles et de contrats intelligents pour vous fournir des nombres aléatoires. Cependant, le service RANDAO est assez lent en ce moment. Ceci n'est pas idéal si vous avez une application qui est souvent utilisée.

3.3 Blocknumber Watcher

Vous pouvez également utiliser un observateur dans votre code, qui vérifie le numéro de bloc jusqu'à ce qu'il corresponde au numéro cible que vous avez défini.

 fonction f (blocknumber, to_address, value_) {
  var filter = web3.eth.filter ('dernière'). watch (
    function (err, blockHash) {

      var target = blocknumber;

      if (web3.eth.blockNumber == target) {
        filter.stopWatching (); // votre fonction ici
        web3.eth.sendTransaction ({à: to_address, à partir de: web3.eth.coinbase, valeur: web3.toWei (value _, "ether")});
        filter = null;

        console.warn ('Bloc atteint');

        if (callback) renvoie le rappel (false);
        sinon, retournez faux;

      } autre {
        console.log ('Attente du bloc');
      }
  });
}

Source . Gist

3.4 Création de contrats intelligents iOlite

iOlite crée un produit qui accepte le langage naturel pour créer des contrats intelligents. Il utilise un moteur de traitement de langage naturel (TAL) de Stanford appelé moteur d'adaptation rapide (FAE). iOlite s'appuie sur la formation communautaire des experts de Solidity. Les experts de la solidité (contributeurs) peuvent définir des structures contenant une ou plusieurs phrases et les attacher au code de contrat intelligent correspondant.

Le moteur de PNL de Stanford a été créé pour comprendre un langage complexe. Le niveau de complexité de la langue dépend de la quantité de formation à la machine. Après une formation appropriée, le moteur sera capable de créer des contrats intelligents complexes. La FAE est capable de créer de tels contrats, car un contrat complexe n'est en réalité pas si complexe. Les experts peuvent diviser la requête en plusieurs petits morceaux de code et l'attacher à une phrase.

Quand quelqu'un introduit plusieurs phrases, il cherche des structures / phrases correspondantes pour construire le contrat 'complexe'. Les contributeurs seront récompensés avec des jetons iOlite via le processus d'exploration de nouvelles structures.

L'avantage d'utiliser iOlite est que les experts en contrat intelligent peuvent résoudre des problèmes difficiles pour vous comme la génération de nombres aléatoires. Vous pouvez trouver plus d'informations sur iOlite.io

Conclusion

Comme vous pouvez le voir, ce n'est pas une tâche facile de générer de vraies entrées aléatoires. Ne comptez pas sur block.timestamp maintenant et block.blockhash comme source de hasard. Une bonne solution comprend une combinaison de plusieurs entrées de données pseudo-aléatoires et l'utilisation d'oracles ou de contrats intelligents pour la rendre plus fiable. Vous devez être sûr à 100% que personne ne peut altérer les données qui sont entrées dans votre contrat intelligent.

Faites attention et réfléchissez à deux fois avant d'implémenter une logique de génération de nombres aléatoires.




Source link