Un matin, j'ai remarqué un article sur sur la plateforme de blockchain Waves.
L'image générale était claire, mais la manière de l'implémenter spécifiquement ne l'était pas. Quels codes, signatures, quoi, où, pourquoi ?
Après plusieurs consultations avec l'auteur de l'oracle, j'ai finalement réussi à combiner la logique du tirage (réalisée en PHP) avec l'algorithme de génération de nombres aléatoires.
- Au moment du début du tournoi/round, nous demandons à l'oracle la première partie du code (R-code).
À ce moment-là, il n'y a aucune information concernant le nombre de joueurs, le nombre de prix, la taille des gains et même l'existence de la loterie. L'oracle délivre, par le biais d'une transaction, un code aléatoire personnel, qui ne peut par la suite être utilisé qu'une seule fois et seulement par celui qui l'a demandé. En passant, le R-code peut être « acheté » (cela inclut le coût de la transaction de demande + compensation à l'oracle pour la transaction de réponse, soit environ $0.015 au taux actuel, le code lui-même est délivré gratuitement) à l'avance, plusieurs d'entre eux, pour ne pas avoir à attendre la transaction de réponse. J'ai mis en place un petit buffer régulièrement mis à jour dans la base de données.
- Le tournoi dure normalement 60 blocs de la plateforme de blockchain Waves, ce qui correspond à environ 1 heure. Le tournoi est considéré comme ayant eu lieu et étant clos si, après 60 blocs, il y a au moins deux tickets, sinon la période d'activité du tournoi est prolongée de 60 blocs supplémentaires.
- Immédiatement après la clôture du tournoi, nous formons et envoyons une transaction de données (pour laquelle nous payons également une commission d'environ $0.005), et si nécessaire, plusieurs, où sont enregistrées toutes les conditions du tirage et la liste ordonnée des joueurs (tickets) parmi lesquels nous devons choisir les gagnants.
- À ce stade, nous avons déjà la première partie du code (R-code) ainsi que l'ID de la transaction de données (TXID). Nous les envoyons à l'oracle pour signature sous la forme d'une concaténation (R-code + TXID), et à nouveau, nous payons une commission + une compensation. L'oracle vérifie les données reçues pour leur unicité et leur appartenance, puis nous renvoie la seconde partie du code (S-code) au format sha256, qui est le point de départ pour le générateur de nombres aléatoires.
- Pour obtenir un nombre aléatoire indiquant le numéro de billet gagnant, nous transformons le S-code des données binaires sha256 en représentation hexadécimale (HEX). Ensuite, à partir de cette chaîne HEX obtenue, nous en déduisons un nombre. Nous prenons le reste de la division de ce nombre par le nombre total de billets (all_tickets) et ajoutons 1 au résultat (pour obtenir un chiffre entre 1 et all_tickets). Au final, nous obtenons le numéro ordinal du gagnant.
- Si selon les conditions du tirage, il y a plusieurs gagnants, nous répétons les opérations précédentes autant de fois que le nombre de places de prix. À chaque fois, nous retirons de la liste le billet qui a déjà gagné et réduisons all_tickets de 1, en utilisant comme S-code le nombre précédemment obtenu.
Analysons un exemple concret et réel, tournoi n°119 :
Au total, 7 billets (all_tickets)
Le coût d'un billet est de 50 pièces (Bet)
La commission de jeu est de 10 % (Fee)
Selon les règles de la loterie, 30 % sont attribués aux prix, c'est-à-dire que dans ce cas, 2 billets doivent recevoir un prix, dont le montant est calculé selon la formule (Bet*all_tickets-Fee)/2.
1. Nous avons obtenu le R-code :
2. Après la clôture du tournoi, nous avons une liste de billets sous forme de paires : numéro + adresse (adresse du portefeuille à partir de laquelle le paiement pour la participation au tournoi a été effectué). Notons que les adresses peuvent se répéter, ce qui signifie qu'un même participant a acheté plusieurs billets pour un même tournoi, ce qui est permis par les règles.
Transaction envoyée :
3. Demande du S-code : avec le commentaire (R-code + TXID) :
RdbAiAhKhveAtR4eyTKq75noMxdcEoxbE6BvojJjM13VE 82JTMzhHM5xEA2fQ9Qscd5QAJU3DAd8nShLjdVHTer5S
4. Nous avons reçu le S-code :
5. Nous avons déterminé les gagnants.
6.
Au final, nous avons dans la blockchain une documentation pas à pas de la procédure de tirage au sort des prix, avec la possibilité de la vérifier à tout moment. Manipuler les résultats du côté de l'organisateur est pratiquement impossible, ou du moins, le faire discrètement n'est plus possible.
déterminer le gagnant n° 1
Tous_les_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 -> nombre gmp: 0xdaf5802953dcb27f89972e38e8900b898733f6a613e6e1c6c5491362c1832596 -> 99037963059744689166154019807924045947962565922868104113173478160267437352342
3. gmp -> modulo (mod=7): 99037963059744689166154019807924045947962565922868104113173478160267437352342 -> 4
4. modulo -> ticket: 4 -> 145
déterminer le gagnant n° 2
Tous_les_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 -> nombre gmp: 0x9560e77525e9ea2db92cdb8484dc52046ccafac7c719b8859ff55f0eb92834a0 -> 67565829218838067182838043983962684143266386786567427968312120473742580659360
3. gmp -> modulo (mod=6): 67565829218838067182838043983962684143266386786567427968312120473742580659360 -> 1
4. modulo -> ticket: 1 -> 139
Fin.Source : habr.com
