Un matin, un article sur le
générateur de nombres aléatoires testé sur la blockchain de la plateforme Waves a attiré mon attention.
L'image globale était compréhensible, mais la méthode de mise en œuvre spécifique ne l'était pas. Des codes, des signatures, quoi, où, pourquoi?
Après quelques consultations avec l'auteur de l'oracle, il s'est avéré combiner la logique du tirage au sort (implémentée en PHP) avec un algorithme d'obtention d'un nombre aléatoire.
- Au début du tournoi / tour, nous demandons à l'oracle la première partie du code (code R).
À l'heure actuelle, il n'y a aucune information sur le nombre de joueurs, ni sur le nombre de prix, ni sur le montant des paiements de prix et généralement sur l'existence d'une loterie. L'oracle à travers une transaction émet un code aléatoire personnel, qui à l'avenir ne pourra être utilisé qu'une seule fois et uniquement pour ceux qui l'ont demandé. Soit dit en passant, le code R peut être «acheté» (se référant au coût de la transaction de demande + compensation Oracle pour la transaction de réponse, il s'agit d'un montant de l'ordre de 0,015 $ au taux actuel, le code lui-même est émis gratuitement) à l'avance immédiatement, afin de ne pas attendre que la transaction de réponse soit reçue plus tard. J'ai fait un petit tampon régulièrement mis à jour dans la base de données. - Le tournoi dure en standard avec 60 blocs de la blockchain de la plateforme Waves, pour le moment c'est environ 1 heure. Un tournoi est considéré comme tenu et fermé si après 60 blocs, il y aura au moins deux billets dedans, sinon le temps d'activité du tournoi sera prolongé par les 60 blocs suivants.
- Immédiatement après la clôture du tournoi, nous formons et envoyons la date de la transaction (nous payons également une commission d'environ 0,005 $ pour celle-ci), si nécessaire, quelques-uns, dans lesquels toutes les conditions du tirage au sort et une liste de joueurs commandée (billets) sont fixées à partir desquelles nous devons choisir les gagnants.
- À ce stade, nous avons déjà la première partie du code (code R) plus l'ID de date de transaction (TXID). Nous les envoyons à l'oracle pour signature sous forme de concaténation (code R + TXID), encore une fois nous payons une commission + une compensation. L'oracle vérifie l'unicité et l'appartenance des données et, en réponse, nous envoie la deuxième partie du code (code S) au format sha256, qui est le point de départ du générateur de nombres aléatoires.
- Pour obtenir un nombre aléatoire qui indiquera le numéro de séquence du ticket gagnant, nous convertissons le code S des données binaires sha256 en une représentation hexadécimale (HEX). Ensuite, à partir de la chaîne HEX résultante, nous obtenons un nombre. Nous obtenons le reste de la division du nombre résultant par le nombre de tickets (all_tickets) et ajoutons au résultat 1 (pour obtenir le nombre 1 à all_tickets). En conséquence, nous obtenons le numéro de série du gagnant.
- S'il y a plusieurs gagnants selon les termes du tirage, nous répétons les opérations précédentes d'un montant égal au nombre de prix. Dans le même temps, chaque fois que nous supprimons le ticket que nous avons déjà gagné de la liste et réduisons all_tickets de 1, et au lieu du code S, nous indiquons le numéro précédent reçu.
Analysons un exemple concret concret, le tournoi n ° 119:
Seulement 7 billets (all_tickets)
Prix du billet 50 pièces (pari)
Frais de jeu 10% (frais)
Selon les conditions de la loterie, 30% obtiennent le prix, soit dans ce cas, 2 billets doivent recevoir un prix dont la taille est calculée selon la formule (Bet * all_tickets-Fee) / 2.
1. Code R reçu:
RdbAiAhKhveAtR4eyTKq75noMxdcEoxbE6BvojJjM13VE2. Après la clôture du tournoi, nous avons une liste de billets sous forme de paires: numéro + adresse (adresse portefeuille à partir de laquelle la participation au tournoi a été payée). Notez que les adresses peuvent être répétées, cela signifie qu'un participant a acheté plusieurs billets dans un tournoi, ce n'est pas interdit par les règles.
Date de transaction envoyée:
82JTMzhHM5xEA2fQ9Qscd5QAJU3DAd8nShLjdVHTer5S3. Code S demandé:
FTF3uRyaa4F2uAyD6z5a3CNbTXbQLc7fSR6CFNVjgZYV avec commentaire (code R + TXID):
RdbAiAhKhveAtR4eyTKq75noMxdcEoxbE6BvojJjM13VE 82JTMzhHM5xEA2fQ9Qscd5QAJU3DAd8nShLjdVHTer5S
4. Code S reçu:
Ri89jHB4UXZDXY6gT1m4LBDXGMTaYzHozMk4nxiuqVXdC5. Les gagnants ont été déterminés.
6.
Paiements envoyésEn conséquence, nous avons dans la blockchain une fixation étape par étape du processus de tirage au sort avec la possibilité de le vérifier à tout moment. Il est presque impossible de manipuler les résultats de l'organisateur, au moins cela ne fonctionnera pas tranquillement.
determine the winner № 1 All_tickets: Index: 1 Ticket:139 Index: 2 Ticket:141 Index: 3 Ticket:143 Index: 4 Ticket:145 Index: 5 Ticket:147 Index: 6 Ticket:149 Index: 7 Ticket:151 1. bin -> hex ( bin2hex(sha256(S-code)) ): Ri89jHB4UXZDXY6gT1m4LBDXGMTaYzHozMk4nxiuqVXdC -> 0xdaf5802953dcb27f89972e38e8900b898733f6a613e6e1c6c5491362c1832596 2. hex -> gmp number: 0xdaf5802953dcb27f89972e38e8900b898733f6a613e6e1c6c5491362c1832596 -> 99037963059744689166154019807924045947962565922868104113173478160267437352342 3. gmp -> modulo (mod=7): 99037963059744689166154019807924045947962565922868104113173478160267437352342 -> 4 4. modulo -> ticket: 4 -> 145 determine the winner № 2 All_tickets: Index: 1 Ticket:139 Index: 2 Ticket:141 Index: 3 Ticket:143 Index: 4 Ticket:147 Index: 5 Ticket:149 Index: 6 Ticket:151 1. bin -> hex ( bin2hex(sha256(previous hex)) ): daf5802953dcb27f89972e38e8900b898733f6a613e6e1c6c5491362c1832596 -> 0x9560e77525e9ea2db92cdb8484dc52046ccafac7c719b8859ff55f0eb92834a0 2. hex -> gmp number: 0x9560e77525e9ea2db92cdb8484dc52046ccafac7c719b8859ff55f0eb92834a0 -> 67565829218838067182838043983962684143266386786567427968312120473742580659360 3. gmp -> modulo (mod=6): 67565829218838067182838043983962684143266386786567427968312120473742580659360 -> 1 4. modulo -> ticket: 1 -> 139 End.