Օգտագործելով պատահական օրակուլ՝ օգտագործելով վիճակախաղի օրինակը

Մի առավոտ ես հանդիպեցի մի հոդվածի մասին ստուգելի պատահական թվերի գեներատոր Waves հարթակի բլոկչեյնի վրա։

Ընդհանուր պատկերը պարզ էր, բայց կոնկրետ իրականացման մեթոդը՝ ոչ։ Որոշ ծածկագրեր, ստորագրություններ, ինչ, որտեղ, ինչու:

Օրակլի հեղինակի հետ մի քանի խորհրդակցություններ, արդյունքում հնարավոր եղավ համատեղել գծագրության տրամաբանությունը (իրականացված PHP-ում) պատահական թվի ստացման ալգորիթմի հետ։

  1. Մրցաշարի/փուլի սկզբում մենք խնդրում ենք օրակուլից ծածկագրի առաջին մասը (R-code):

    Այս պահին տեղեկություններ չկան խաղացողների քանակի, մրցանակային տեղերի, մրցանակների վճարումների չափի, ընդհանրապես վիճակախաղի առկայության մասին։ Oracle-ը գործարքի միջոցով թողարկում է անձնական պատահական ծածկագիր, որն այնուհետև կարող է օգտագործվել միայն մեկ անգամ և միայն նրանց կողմից, ովքեր դա խնդրել են: Ի դեպ, R-կոդը կարելի է «գնել» (նկատի ունի հարցման գործարքի արժեքը + փոխհատուցում Oracle-ին պատասխան գործարքի համար, սա կազմում է մոտ 0.015 ԱՄՆ դոլար ընթացիկ փոխարժեքով, կոդը ինքնին տրվում է անվճար: ) մի քանի անգամ նախօրոք, որպեսզի չսպասեք պատասխան գործարքի ստացմանը ավելի ուշ։ Ես շտեմարանում պարբերաբար թարմացվող փոքրիկ բուֆեր եմ ստեղծել:

  2. Մրցաշարը սովորաբար տևում է Waves պլատֆորմի բլոկչեյնի 60 բլոկ, այս պահին այն մոտավորապես 1 ժամ է։ Մրցաշարը համարվում է ավարտված և փակված, եթե 60 բլոկից հետո դրանում կա առնվազն երկու տոմս, հակառակ դեպքում մրցաշարի գործունեության ժամանակը երկարաձգվում է հաջորդ 60 բլոկների համար:
  3. Մրցաշարի փակումից անմիջապես հետո մենք ստեղծում և ուղարկում ենք ամսաթվի գործարք (մենք նաև վճարում ենք դրա համար մոտավորապես 0.005 դոլար միջնորդավճար), անհրաժեշտության դեպքում մի քանիսը, որոնցում գրանցված են վիճակահանության բոլոր պայմանները և խաղացողների պատվիրված ցուցակը (տոմսերը): որոնցից մենք պետք է ընտրենք հաղթողներին:
  4. Այս փուլում մենք արդեն ունենք կոդի առաջին մասը (R-code) գումարած գործարքի ամսաթվի ID-ն (TXID): Ստորագրության ենք ուղարկում Oracle՝ կապակցման ձևով (R-code + TXID), կրկին վճարում ենք միջնորդավճար + փոխհատուցում։ Oracle-ը ստուգում է ստացված տվյալները եզակիության և պատկանելիության համար, և ի պատասխան մեզ ուղարկում է կոդի երկրորդ մասը (S-code) sha256 ձևաչափով, որը մեկնարկային կետ է պատահական թվերի գեներատորի համար։
  5. Պատահական թիվ ստանալու համար, որը ցույց կտա հաղթող տոմսի հաջորդական համարը, մենք S-կոդը sha256 երկուական տվյալներից վերածում ենք տասնվեցական (HEX) ներկայացման: Այնուհետև ստացված HEX տողից ստանում ենք թիվ։ Ստացված թիվը տոմսերի թվի վրա (բոլոր_տոմսերը) բաժանելու մնացորդը ստանում ենք և արդյունքին ավելացնում ենք 1 (բոլոր_տոմսերից առաջ 1 թիվը ստանալու համար)։ Արդյունքում ստանում ենք հաղթողի սերիական համարը։
  6. Եթե, ըստ վիճակահանության, կան մի քանի հաղթողներ, ապա մենք կրկնում ենք նախորդ գործողությունները մրցանակային տեղերի թվին հավասար քանակությամբ։ Այս դեպքում ամեն անգամ ցուցակից հանում ենք արդեն շահած տոմսը և բոլոր_տոմսերը կրճատում ենք 1-ով, իսկ S-code-ի փոխարեն նշում ենք ստացված նախորդ թիվը։

Դիտարկենք կոնկրետ իրական օրինակ՝ թիվ 119 մրցաշարը.

Ընդհանուր 7 տոմս (all_tickets)
Տոմսի արժեքը 50 մետաղադրամ (Խաղադրույք)
Խաղի վճար 10% (վճար)

Ըստ վիճակախաղի պայմանների՝ 30%-ը բաժին է ընկնում մրցանակային գումարին, այսինքն. այս դեպքում 2 տոմս պետք է ստանա մրցանակ, որի չափը հաշվարկվում է (Bet*all_tickets-Fee) բանաձեւով/2։

1. Ստացել է R-կոդ. RdbAiAhKhveAtR4eyTKq75noMxdcEoxbE6BvojJjM13VE

2. Մրցաշարի փակումից հետո մենք ունենք տոմսերի ցուցակ զույգերի տեսքով՝ համար + հասցե (դրամապանակի հասցեն, որից վճարվել է մրցաշարին մասնակցելու համար): Խնդրում ենք նկատի ունենալ, որ հասցեները կարող են կրկնվել, սա նշանակում է, որ մեկ մասնակից գնել է մեկ մրցաշարի մի քանի տոմս, դա արգելված չէ կանոններով:

Գործարքի ուղարկման ամսաթիվը. 82JTMzhHM5xEA2fQ9Qscd5QAJU3DAd8nShLjdVHTer5S

3. Պահանջվող S-կոդ. FTF3uRyaa4F2uAyD6z5a3CNbTXbQLc7fSR6CFNVjgZYV մեկնաբանությամբ (R-code + TXID):
RdbAiAhKhveAtR4eyTKq75noMxdcEoxbE6BvojJjM13VE 82JTMzhHM5xEA2fQ9Qscd5QAJU3DAd8nShLjdVHTer5S

4. Ստացված S-կոդ. Ri89jHB4UXZDXY6gT1m4LBDXGMTaYzHozMk4nxiuqVXdC

5. Որոշվեցին հաղթողները.

6. Ուղարկված վճարումներ

Արդյունքում մենք ունենք մրցանակների խաղարկության ընթացակարգի քայլ առ քայլ ձայնագրություն բլոկչեյնում՝ այն ցանկացած պահի ստուգելու հնարավորությամբ։ Կազմակերպչի համար գրեթե անհնար է շահարկել արդյունքները, համենայնդեպս, դա այլեւս հնարավոր չի լինի անել աննկատ։

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: www.habr.com

Добавить комментарий