Op een ochtend viel een artikel over op de blockchain van het Waves-platform.
Het algemene plaatje was duidelijk, maar de specifieke implementatiemethode niet. Welke codes, handtekeningen, wat, waar, waarom?
Na enkele consultaties met de auteur van de oracle, lukte het om de logica van de trekking (gerealiseerd in PHP) te combineren met het algoritme voor het genereren van een willekeurig nummer.
- Op het moment van de start van het toernooi/ronde vragen we de oracle om het eerste deel van de code (R-code).
Op dat moment is er geen informatie over het aantal spelers, het aantal prijzen, de hoogte van de prijzen en überhaupt het bestaan van de loterij. De oracle geeft via een transactie een persoonlijk willekeurig nummer dat later maar één keer kan worden gebruikt en alleen door degene die het heeft opgevraagd. Overigens kan de R-code van tevoren 'aangekocht' worden (d.w.z. de kosten van de aanvraagtransactie + compensatie voor de oracle voor de antwoordtransactie, dat is ongeveer $0.015 tegen de huidige koers, de code zelf is gratis), zodat je niet hoeft te wachten op de ontvangst van de antwoordtransactie. Ik heb een kleine regelmatig bijgevulde buffer in de database gemaakt.
- Het toernooi duurt standaard 60 blokken van de Waves blockchain, momenteel is dat ongeveer 1 uur. Het toernooi wordt als geldig en gesloten beschouwd als er na 60 blokken minimaal twee tickets in zijn, anders wordt de actietijd van het toernooi verlengd met nog eens 60 blokken.
- Direct na de sluiting van het toernooi creƫren en versturen we de datatransactie (waarvoor we ook een vergoeding betalen van ongeveer $0.005), indien nodig meerdere, waarin alle voorwaarden van de trekking en de geordende lijst van spelers (tickets) zijn vastgelegd waarvan we de winnaars moeten selecteren.
- In dit stadium hebben we al het eerste deel van de code (R-code) plus de ID van de datatransactie (TXID). We sturen ze naar de oracle voor ondertekening in de vorm van concatenatie (R-code + TXID), waarbij we opnieuw een vergoeding + compensatie betalen. De oracle controleert de ontvangen gegevens op uniekheid en eigendom, en stuurt ons als antwoord het tweede deel van de code (S-code) in sha256-formaat, dat het startpunt is voor de willekeurige getallengenerator.
- Om een willekeurig getal te krijgen dat het volgnummer van het winnende ticket aangeeft, zetten we de S-code van de binaire sha256-gegevens om in een hexadecimale (HEX) weergave. Vervolgens halen we uit de verkregen HEX-string een getal. We nemen de rest van de deling van dat getal door het aantal tickets (all_tickets) en tellen daar 1 bij op (om een cijfer van 1 tot all_tickets te krijgen). Uiteindelijk krijgen we het volgnummer van de winnaar.
- Als er volgens de wedstrijdvoorwaarden meerdere winnaars zijn, herhalen we de voorgaande bewerkingen in een hoeveelheid die gelijk is aan het aantal prijzengeldplaatsen. Bij elk keer verwijderen we het ticket dat al gewonnen heeft uit de lijst en verminderen we all_tickets met 1, en in plaats van S-code gebruiken we het eerder verkregen getal.
Laten we een specifiek echt voorbeeld bekijken, toernooi ā119:
In totaal 7 tickets (all_tickets)
De prijs van een ticket is 50 munten (Bet)
Speelbelasting 10% (Fee)
Volgens de loterijvoorwaarden gaat 30% naar de prijzen, d.w.z. in dit geval moeten 2 tickets een prijs ontvangen, waarvan de grootte wordt berekend volgens de formule (Bet*all_tickets-Fee)/2.
1. Verkregen R-code:
2. Na het sluiten van het toernooi hebben we een lijst van tickets in de vorm van paren: nummer + adres (het adres van de wallet waarvan de betaling voor deelname aan het toernooi is gedaan). Merk op dat de adressen kunnen herhalen, dat betekent dat ƩƩn deelnemer meerdere tickets voor ƩƩn toernooi heeft gekocht, wat niet in strijd is met de regels.
Verstuurde datumtransactie:
3. Gevraagd om S-code: met een opmerking (R-code + TXID):
RdbAiAhKhveAtR4eyTKq75noMxdcEoxbE6BvojJjM13VE 82JTMzhHM5xEA2fQ9Qscd5QAJU3DAd8nShLjdVHTer5S
4. Verkregen S-code:
5. Winnaars bepaald.
6.
Als resultaat hebben we in de blockchain een stapsgewijze vastlegging van de procedure voor het verloten van prijzen met de mogelijkheid om deze op elk moment te controleren. Het is praktisch onmogelijk om de resultaten vanuit de sponsor te vervalsen, althans het zal niet meer onopgemerkt mogelijk zijn.
bepaal de winnaar ā 1
Alle_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)) ): Ri89jHB4UXZDXY6gT1m4LBDXXGMTaYzHozMk4nxiuqVXdC -> 0xdaf5802953dcb27f89972e38e8900b898733f6a613e6e1c6c5491362c1832596
2. hex -> gmp nummer: 0xdaf5802953dcb27f89972e38e8900b898733f6a613e6e1c6c5491362c1832596 -> 99037963059744689166154019807924045947962565922868104113173478160267437352342
3. gmp -> modulo (mod=7): 99037963059744689166154019807924045947962565922868104113173478160267437352342 -> 4
4. modulo -> ticket: 4 -> 145
bepaal de winnaar ā 2
Alle_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 nummer: 0x9560e77525e9ea2db92cdb8484dc52046ccafac7c719b8859ff55f0eb92834a0 -> 67565829218838067182838043983962684143266386786567427968312120473742580659360
3. gmp -> modulo (mod=6): 67565829218838067182838043983962684143266386786567427968312120473742580659360 -> 1
4. modulo -> ticket: 1 -> 139
Einde.Bron: habr.com
