Utiliser un oracle aléatoire en utilisant l'exemple d'une loterie

Un matin, je suis tombé sur un article sur générateur de nombres aléatoires vérifiable sur la blockchain de la plateforme Waves.

Le tableau d’ensemble était clair, mais la méthode spécifique de mise en œuvre ne l’était pas. Des codes, des signatures, quoi, où, pourquoi ?

Plusieurs consultations avec l'auteur de l'oracle ont permis de combiner la logique de dessin (implémentée en PHP) avec un algorithme d'obtention d'un nombre aléatoire.

  1. Au début du tournoi/tour, nous demandons la première partie du code (R-code) à l'oracle.

    À l'heure actuelle, il n'y a aucune information sur le nombre de joueurs, le nombre de places gagnées, le montant des prix payés ou l'existence de la loterie en général. L'oracle, au travers d'une transaction, émet un code aléatoire personnel, qui ne peut ensuite être utilisé qu'une seule fois et uniquement par ceux qui l'ont demandé. À propos, le code R peut être « acheté » (c'est-à-dire le coût de la transaction de demande + compensation à l'oracle pour la transaction de réponse, il s'agit d'un montant d'environ 0.015 $ au taux actuel, le code lui-même est émis gratuitement ) plusieurs fois à l'avance, afin de ne pas attendre ultérieurement la réception de la transaction de réponse. J'ai fait un petit buffer régulièrement mis à jour dans la base de données.

  2. Le tournoi dure généralement 60 blocs de la blockchain de la plateforme Waves, pour le moment il dure environ 1 heure. Le tournoi est considéré comme terminé et fermé si, après 60 blocs, il contient au moins deux tickets, sinon la durée du tournoi est prolongée pour les 60 blocs suivants.
  3. Immédiatement après la clôture du tournoi, nous générons et envoyons une transaction de date (nous payons également une commission d'environ 0.005 $ pour cela), si nécessaire, plusieurs, dans lesquelles sont enregistrées toutes les conditions du tirage et une liste ordonnée des joueurs (billets) parmi lesquels nous devons sélectionner les gagnants.
  4. A ce stade, nous disposons déjà de la première partie du code (R-code) plus l'ID de la date de transaction (TXID). Nous les envoyons pour signature à l'oracle sous forme de concaténation (R-code + TXID), là encore nous payons une commission + compensation. L'oracle vérifie l'unicité et l'appartenance des données reçues et nous envoie en réponse 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.
  5. 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 en divisant le nombre obtenu par le nombre de billets (all_tickets) et ajoutons 1 au résultat (pour obtenir le numéro 1 avant all_tickets). En conséquence, nous obtenons le numéro de série du gagnant.
  6. Si, selon les conditions du tirage au sort, il y a plusieurs gagnants, alors on répète les opérations précédentes à hauteur d'un montant égal au nombre de places. Dans ce cas, chaque fois que nous supprimons de la liste un ticket déjà gagné et réduisons all_tickets de 1, et au lieu du S-code nous indiquons le numéro précédent reçu.

Regardons un exemple réel précis, le tournoi n°119 :

Total 7 billets (all_tickets)
Le billet coûte 50 pièces (pari)
Frais de jeu 10 % (Frais)

Selon les conditions de la loterie, 30 % vont au prix en argent, c'est-à-dire dans ce cas, 2 tickets doivent recevoir un prix dont le montant est calculé selon la formule (Bet*all_tickets-Fee)/2.

1. Code R reçu : RdbAiAhKhveAtR4eyTKq75noMxdcEoxbE6BvojJjM13VE

2. Après la clôture du tournoi, nous avons une liste de tickets sous forme de paires : numéro + adresse (l'adresse du wallet à partir duquel le paiement de la participation au tournoi a été effectué). Veuillez noter que les adresses peuvent être répétées, cela signifie qu'un participant a acheté plusieurs billets pour un tournoi ; ce n'est pas interdit par le règlement.

Date de transaction envoyée : 82JTMzhHM5xEA2fQ9Qscd5QAJU3DAd8nShLjdVHTer5S

3. Code S demandé : FTF3uRyaa4F2uAyD6z5a3CNbTXbQLc7fSR6CFNVjgZYV avec commentaire (R-code + TXID) :
RdbAiAhKhveAtR4eyTKq75noMxdcEoxbE6BvojJjM13VE 82JTMzhHM5xEA2fQ9Qscd5QAJU3DAd8nShLjdVHTer5S

4. Code S reçu : Ri89jHB4UXZDXY6gT1m4LBDXGMTaYzHozMk4nxiuqVXdC

5. Les gagnants ont été déterminés.

6. Paiements envoyés

En conséquence, nous disposons d'un enregistrement étape par étape de la procédure de tirage au sort dans la blockchain avec la possibilité de la vérifier à tout moment. Il est quasiment impossible pour l'organisateur de manipuler les résultats ; du moins, il ne sera plus possible de le faire inaperçu.

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.

Source: habr.com

Ajouter un commentaire