Մի առավոտ ես հանդիպեցի մի հոդվածի մասին
Ընդհանուր պատկերը պարզ էր, բայց կոնկրետ իրականացման մեթոդը՝ ոչ։ Որոշ ծածկագրեր, ստորագրություններ, ինչ, որտեղ, ինչու:
Օրակլի հեղինակի հետ մի քանի խորհրդակցություններ, արդյունքում հնարավոր եղավ համատեղել գծագրության տրամաբանությունը (իրականացված PHP-ում) պատահական թվի ստացման ալգորիթմի հետ։
- Մրցաշարի/փուլի սկզբում մենք խնդրում ենք օրակուլից ծածկագրի առաջին մասը (R-code):
Այս պահին տեղեկություններ չկան խաղացողների քանակի, մրցանակային տեղերի, մրցանակների վճարումների չափի, ընդհանրապես վիճակախաղի առկայության մասին։ Oracle-ը գործարքի միջոցով թողարկում է անձնական պատահական ծածկագիր, որն այնուհետև կարող է օգտագործվել միայն մեկ անգամ և միայն նրանց կողմից, ովքեր դա խնդրել են: Ի դեպ, R-կոդը կարելի է «գնել» (նկատի ունի հարցման գործարքի արժեքը + փոխհատուցում Oracle-ին պատասխան գործարքի համար, սա կազմում է մոտ 0.015 ԱՄՆ դոլար ընթացիկ փոխարժեքով, կոդը ինքնին տրվում է անվճար: ) մի քանի անգամ նախօրոք, որպեսզի չսպասեք պատասխան գործարքի ստացմանը ավելի ուշ։ Ես շտեմարանում պարբերաբար թարմացվող փոքրիկ բուֆեր եմ ստեղծել:
- Մրցաշարը սովորաբար տևում է Waves պլատֆորմի բլոկչեյնի 60 բլոկ, այս պահին այն մոտավորապես 1 ժամ է։ Մրցաշարը համարվում է ավարտված և փակված, եթե 60 բլոկից հետո դրանում կա առնվազն երկու տոմս, հակառակ դեպքում մրցաշարի գործունեության ժամանակը երկարաձգվում է հաջորդ 60 բլոկների համար:
- Մրցաշարի փակումից անմիջապես հետո մենք ստեղծում և ուղարկում ենք ամսաթվի գործարք (մենք նաև վճարում ենք դրա համար մոտավորապես 0.005 դոլար միջնորդավճար), անհրաժեշտության դեպքում մի քանիսը, որոնցում գրանցված են վիճակահանության բոլոր պայմանները և խաղացողների պատվիրված ցուցակը (տոմսերը): որոնցից մենք պետք է ընտրենք հաղթողներին:
- Այս փուլում մենք արդեն ունենք կոդի առաջին մասը (R-code) գումարած գործարքի ամսաթվի ID-ն (TXID): Ստորագրության ենք ուղարկում Oracle՝ կապակցման ձևով (R-code + TXID), կրկին վճարում ենք միջնորդավճար + փոխհատուցում։ Oracle-ը ստուգում է ստացված տվյալները եզակիության և պատկանելիության համար, և ի պատասխան մեզ ուղարկում է կոդի երկրորդ մասը (S-code) sha256 ձևաչափով, որը մեկնարկային կետ է պատահական թվերի գեներատորի համար։
- Պատահական թիվ ստանալու համար, որը ցույց կտա հաղթող տոմսի հաջորդական համարը, մենք S-կոդը sha256 երկուական տվյալներից վերածում ենք տասնվեցական (HEX) ներկայացման: Այնուհետև ստացված HEX տողից ստանում ենք թիվ։ Ստացված թիվը տոմսերի թվի վրա (բոլոր_տոմսերը) բաժանելու մնացորդը ստանում ենք և արդյունքին ավելացնում ենք 1 (բոլոր_տոմսերից առաջ 1 թիվը ստանալու համար)։ Արդյունքում ստանում ենք հաղթողի սերիական համարը։
- Եթե, ըստ վիճակահանության, կան մի քանի հաղթողներ, ապա մենք կրկնում ենք նախորդ գործողությունները մրցանակային տեղերի թվին հավասար քանակությամբ։ Այս դեպքում ամեն անգամ ցուցակից հանում ենք արդեն շահած տոմսը և բոլոր_տոմսերը կրճատում ենք 1-ով, իսկ S-code-ի փոխարեն նշում ենք ստացված նախորդ թիվը։
Դիտարկենք կոնկրետ իրական օրինակ՝ թիվ 119 մրցաշարը.
Ընդհանուր 7 տոմս (all_tickets)
Տոմսի արժեքը 50 մետաղադրամ (Խաղադրույք)
Խաղի վճար 10% (վճար)
Ըստ վիճակախաղի պայմանների՝ 30%-ը բաժին է ընկնում մրցանակային գումարին, այսինքն. այս դեպքում 2 տոմս պետք է ստանա մրցանակ, որի չափը հաշվարկվում է (Bet*all_tickets-Fee) բանաձեւով/2։
1. Ստացել է R-կոդ.
2. Մրցաշարի փակումից հետո մենք ունենք տոմսերի ցուցակ զույգերի տեսքով՝ համար + հասցե (դրամապանակի հասցեն, որից վճարվել է մրցաշարին մասնակցելու համար): Խնդրում ենք նկատի ունենալ, որ հասցեները կարող են կրկնվել, սա նշանակում է, որ մեկ մասնակից գնել է մեկ մրցաշարի մի քանի տոմս, դա արգելված չէ կանոններով:
Գործարքի ուղարկման ամսաթիվը.
3. Պահանջվող S-կոդ.
RdbAiAhKhveAtR4eyTKq75noMxdcEoxbE6BvojJjM13VE 82JTMzhHM5xEA2fQ9Qscd5QAJU3DAd8nShLjdVHTer5S
4. Ստացված S-կոդ.
5. Որոշվեցին հաղթողները.
Արդյունքում մենք ունենք մրցանակների խաղարկության ընթացակարգի քայլ առ քայլ ձայնագրություն բլոկչեյնում՝ այն ցանկացած պահի ստուգելու հնարավորությամբ։ Կազմակերպչի համար գրեթե անհնար է շահարկել արդյունքները, համենայնդեպս, դա այլեւս հնարավոր չի լինի անել աննկատ։
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