En morgen stødte jeg på en artikel om på blockchainen Waves platform.
Det overordnede billede var klart, men metoden til den specifikke implementering - det var uklart. Hvad med koderne, underskrifterne, hvad, hvor, hvorfor?
Efter nogle konsultationer med forfatteren af oraklet lykkedes det mig at kombinere logikken for lodtrækningen (implementeret i PHP) med algoritmen for at generere et tilfældigt tal.
- Ved starten af turneringen/runden anmoder vi oraklet om den første del af koden (R-code).
På det tidspunkt er der ingen information om antallet af spillere, antallet af præmiepladser, størrelsen af præmieudbetalingerne og overhovedet eksistensen af lotteriet. Oraklet giver gennem en transaktion en personlig tilfældig kode, der kun kan bruges én gang af den, der har anmodet om den. For resten kan R-code "købes" (dette refererer til omkostningen ved transaktionsanmodningen + kompensation til oraklet for den svarende transaktion, hvilket anslås at koste omkring $0.015 efter den nuværende kurs, selve koden gives gratis) på forhånd, så man ikke skal vente på at modtage den svarende transaktion. Jeg lavede en lille regelmæssigt opdateret buffer i databasen.
- Turneringen varer standard 60 blokke på Waves blockchain, hvilket svarer til cirka 1 time. Turneringen betragtes som valid og afsluttet, hvis der efter 60 blokke er mindst to billetter; ellers forlænges turneringens aktive periode med de næste 60 blokke.
- Umiddelbart efter turneringsafslutningen danner og sender vi data-transaktionen (vi betaler også et gebyr på cirka $0.005 for den), om nødvendigt flere, hvori alle betingelser for lodtrækningen og den ordnede liste over spillere (billetter), hvorfra vi skal vælge vindere, er fastlagt.
- På dette stadium har vi allerede den første del af koden (R-code) plus ID for data-transaktionen (TXID). Vi sender dem til oraklet for underskrivelse i form af en konkatenering (R-code + TXID), igen betaler vi gebyr+kompensation. Oraklet kontrollerer de modtagne data for unikhed og ejerskab og sender os til svar den anden del af koden (S-code) i sha256-format, som er udgangspunktet for den tilfældige talgenerator.
- For at få et tilfældigt nummer, der angiver rækkenummeret for den vindende billet, konverterer vi S-koden fra binære data i sha256 til en hexadecimalt (HEX) format. Derefter får vi et tal fra den resulterende HEX-streng. Vi tager resten af divisionen af det opnåede tal med antallet af billetter (all_tickets) og lægger 1 til resultatet (for at få et tal fra 1 til all_tickets). I sidste ende får vi vindernes rækkenummer.
- Hvis der ifølge lodtrækningsbetingelserne er flere vindere, gentager vi de tidligere operationer et antal gange svarende til antallet af præmiepladser. Hver gang fjerner vi billetten, der allerede har vundet, fra listen og reducerer all_tickets med 1, mens vi i stedet angiver den tidligere opnåede værdi som S-kode.
Lad os se på et konkret eksempel, turnering nr. 119:
I alt 7 billetter (all_tickets)
Billetpris 50 mønter (Bet)
Spilafgift 10% (Fee)
I henhold til lotteribetingelserne går 30% til præmier, dvs. i dette tilfælde skal 2 billetter modtage præmien, hvis størrelse beregnes efter formlen (Bet * all_tickets - Fee) / 2.
1. Vi fik R-koden:
2. Efter turneringens afslutning har vi en liste over billetter i form af par: nummer + adresse (adressen på wallet, hvorfra deltagergebyret blev betalt). Bemærk, at adresserne kan gentages, hvilket betyder, at én deltager har købt flere billetter til én turnering, hvilket ikke er forbudt af reglerne.
Sendt transaktionsdato:
3. Anmodede om S-kode: med kommentar (R-kode + TXID):
RdbAiAhKhveAtR4eyTKq75noMxdcEoxbE6BvojJjM13VE 82JTMzhHM5xEA2fQ9Qscd5QAJU3DAd8nShLjdVHTer5S
4. Vi fik S-koden:
5. Vindere blev bestemt.
6.
Som resultat har vi en trinvis registrering af lodtrækningsproceduren i blockchainen med mulighed for at kontrollere den når som helst. At manipulere med resultaterne fra arrangøren er praktisk talt umuligt, i det mindste er det ikke længere muligt at gøre det uset.
bestem vinderen nr. 1
Alle_billetter:
Index: 1 Billet:139
Index: 2 Billet:141
Index: 3 Billet:143
Index: 4 Billet:145
Index: 5 Billet:147
Index: 6 Billet:149
Index: 7 Billet:151
1. bin -> hex ( bin2hex(sha256(S-kode)) ): Ri89jHB4UXZDXY6gT1m4LBDXGMTaYzHozMk4nxiuqVXdC -> 0xdaf5802953dcb27f89972e38e8900b898733f6a613e6e1c6c5491362c1832596
2. hex -> gmp nummer: 0xdaf5802953dcb27f89972e38e8900b898733f6a613e6e1c6c5491362c1832596 -> 99037963059744689166154019807924045947962565922868104113173478160267437352342
3. gmp -> modulo (mod=7): 99037963059744689166154019807924045947962565922868104113173478160267437352342 -> 4
4. modulo -> billet: 4 -> 145
bestem vinderen nr. 2
Alle_billetter:
Index: 1 Billet:139
Index: 2 Billet:141
Index: 3 Billet:143
Index: 4 Billet:147
Index: 5 Billet:149
Index: 6 Billet:151
1. bin -> hex ( bin2hex(sha256(tidligere hex)) ): daf5802953dcb27f89972e38e8900b898733f6a613e6e1c6c5491362c1832596 -> 0x9560e77525e9ea2db92cdb8484dc52046ccafac7c719b8859ff55f0eb92834a0
2. hex -> gmp nummer: 0x9560e77525e9ea2db92cdb8484dc52046ccafac7c719b8859ff55f0eb92834a0 -> 67565829218838067182838043983962684143266386786567427968312120473742580659360
3. gmp -> modulo (mod=6): 67565829218838067182838043983962684143266386786567427968312120473742580659360 -> 1
4. modulo -> billet: 1 -> 139
Slut.Kilde: habr.com
