Blockchain-da tasodifiy RSA

Muammo bor - markazlashtirilmagan tarmoqda tasodifiy raqamni yaratish qiyin. Deyarli barcha blokcheynlar bunga duch kelishgan. Haqiqatan ham, foydalanuvchilar o'rtasida ishonch bo'lmagan tarmoqlarda, inkor etilmaydigan tasodifiy raqamni yaratish ko'plab muammolarni hal qiladi.

Ushbu maqolada biz misol sifatida o'yinlardan foydalangan holda muammoni qanday hal qilishga muvaffaq bo'lganimizni aytib beramiz. Ulardan birinchisi edi To'lqinlar Rojdestvo daraxti. Rivojlanish uchun bizga tasodifiy sonlar generatori kerak edi.

Blockchain-da tasodifiy RSA

Dastlab, biz blokcheyndan olingan ma'lumotlar asosida raqam yaratishni rejalashtirgan edik. Biroq, keyin ma'lum bo'ldi: raqamni manipulyatsiya qilish mumkin, ya'ni yechim mos emas.

Biz vaqtinchalik yechim topdik: commit-expand sxemasidan foydalaning. Server 1 dan 5 gacha bo'lgan raqamni taxmin qildi, unga tuz qo'shdi va natijani foydalanib, xeshladi Keccak funktsiyalari. Server oldindan saqlangan raqam bilan aqlli shartnomani joylashtirdi. Ma'lum bo'lishicha, o'yin foydalanuvchining xesh tomonidan yashiringan raqamni taxmin qilishiga to'g'ri keladi.

O'yinchi pul tikdi va server aqlli shartnomaga yashirin raqam va "tuz" ni yubordi. Oddiy qilib aytganda, u kartalarni ochib berdi. Shundan so‘ng server raqamlarni tekshirib chiqdi va foydalanuvchi g‘alaba qozonadimi yoki yutqazadimi, degan qarorga keldi.

Agar server tekshirish uchun raqam yoki "tuz" yubormagan bo'lsa, foydalanuvchi g'alaba qozondi. Bunday holda, har bir o'yin uchun aqlli shartnomani oldindan o'rnatish va unga potentsial yutuqlarni kiritish kerak edi. Bu noqulay, vaqt talab qiladigan va qimmat bo'lib chiqdi. O'sha paytda boshqa xavfsiz echim yo'q edi.

Yaqinda Tradisys jamoasi Waves protokoliga funksiya qo'shishni taklif qildi rsaVerify(). U ochiq va yopiq kalit asosida RSA imzosining haqiqiyligini tekshiradi. Natijada, xususiyat qo'shildi.

Biz uchta o'yin ishlab chiqdik: Zar roliki, Coin Flip и To'lqinlarga minish. Ularning har biri tasodifiy raqamlar texnologiyasini qo'llaydi. Keling, bu qanday ishlashini aniqlaymiz.

Blockchain-da tasodifiy RSA

Misol sifatida Ride on Waves yordamida tasodifiy sonni yaratishni ko'rib chiqaylik. Aqlli shartnomani topish mumkin shu yerda.

Yorliqqa o'ting stsenariy va tanlang Dekompilyatsiya qilingan. Siz aqlli shartnoma kodini (aka skript) ko'rasiz.

Blockchain-da tasodifiy RSA

Smart kontrakt kodi bir qator funktsiyalarni o'z ichiga oladi. @Callable sifatida belgilanganlar yordamida ishga tushirish mumkin Chaqiruv operatsiyalari. Bizni ikkita funktsiya qiziqtiradi: garov и qaytmoq:

  • func bet (playerChoice)
  • func olib tashlash (gameId, rsaSign)

1. Foydalanuvchi segment uzunligini va tikish hajmini tanlaydi.

Blockchain-da tasodifiy RSA

2. Mijoz pul tikish funksiyasini yaratadi. Yuqoridagi rasm uchun shunday bo'ladi tikish("50").

3. Mijoz Invocation tranzaktsiyasini aqlli shartnoma manziliga yuboradi (InvocationTx translyatsiyasi). Tranzaksiya qo'ng'iroq parametri sifatida tikish funktsiyasini o'z ichiga oladi. Bu shuni anglatadiki, Invocation tranzaksiya aqlli shartnomada tikish funktsiyasini (tanlov: String) bajarilishini boshlaydi.

Blockchain-da tasodifiy RSA

4. Gambling funktsiyasini ko'rib chiqing:

@Callable(i)
func bet (playerChoice) = {
    let newGameNum = IncrementGameNum()
    let gameId = toBase58String(i.transactionId)
    let pmt = extract(i.payment)
    let betNotInWaves = isDefined(pmt.assetId)
    let feeNotInWaves = isDefined(pmt.assetId)
    let winAmt = ValidateBetAndDefineWinAmt(pmt.amount, playerChoice)
    let txIdUsed = isDefined(getString(this, gameId))
    if (betNotInWaves)
        then throw ("Bet amount must be in Waves")
        else if (feeNotInWaves)
            then throw ("Transaction's fee must be in Waves")
            else if (txIdUsed)
                then throw ("Passed txId had been used before. Game aborted.")
                else {
                    let playerPubKey58 = toBase58String(i.callerPublicKey)
                    let gameDataStr = FormatGameDataStr(STATESUBMITTED, playerChoice, playerPubKey58, height, winAmt, "")
                    ScriptResult(WriteSet(cons(DataEntry(RESERVATIONKEY, ValidateAndIncreaseReservedAmt(winAmt)), cons(DataEntry(GAMESCOUNTERKEY, newGameNum), cons(DataEntry(gameId, gameDataStr), nil)))), TransferSet(cons(ScriptTransfer(SERVER, COMMISSION, unit), nil)))
                    }
    }

Funktsiya aqlli shartnoma holatiga yangi o'yin yozadi. Aynan:

  • Yangi o'yin uchun noyob identifikator (o'yin identifikatori)
  • O'yin holati = TAQDIM ETILGAN
  • O'yinchining tanlovi (segment uzunligi 50)
  • Ochiq kalit
  • Potentsial g'alabalar (o'yinchining garoviga qarab)

Blockchain-da tasodifiy RSA

Blokcheyndagi ma'lumotlar yozuvi shunday ko'rinadi (kalit-qiymat):

{
    "type": "string",
    "value": "03WON_0283_448t8Jn9P3717UnXFEVD5VWjfeGE5gBNeWg58H2aJeQEgJ_06574069_09116020000_0229",
    "key": "2GKTX6NLTgUrE4iy9HtpSSHpZ3G8W4cMfdjyvvnc21dx"
  }

"Kalit" (kalit) - o'yin identifikatori Yangi o'yin. Qolgan ma'lumotlar "qiymat" maydonining qatorida joylashgan. Ushbu yozuvlar yorliqda saqlanadi ma'lumotlar aqlli shartnoma:

Blockchain-da tasodifiy RSA

Blockchain-da tasodifiy RSA

5. Server aqlli shartnomaga “qarang” va blokcheyn Api yordamida yuborilgan tranzaksiyani (yangi o‘yin) topadi. Yangi o'yinning o'yin identifikatori allaqachon blokcheynda qayd etilgan, ya'ni endi uni o'zgartirish yoki ta'sir qilish mumkin emas.

6. Server qaytarib olish funksiyasini yaratadi (gameId, rsaSign). Masalan, bu kabi:

withdraw ("FwsuaaShC6DMWdSWQ5osGWtYkVbTEZrsnxqDbVx5oUpq", "base64:Gy69dKdmXUEsAmUrpoWxDLTQOGj5/qO8COA+QjyPVYTAjxXYvEESJbSiCSBRRCOAliqCWwaS161nWqoTL/TltiIvw3nKyd4RJIBNSIgEWGM1tEtNwwnRwSVHs7ToNfZ2Dvk/GgPUqLFDSjnRQpTHdHUPj9mQ8erWw0r6cJXrzfcagKg3yY/0wJ6AyIrflR35mUCK4cO7KumdvC9Mx0hr/ojlHhN732nuG8ps4CUlRw3CkNjNIajBUlyKQwpBKmmiy3yJa/QM5PLxqdppmfFS9y0sxgSlfLOgZ51xRDYuS8NViOA7c1JssH48ZtDbBT5yqzRJXs3RnmZcMDr/q0x6Bg==")

7. Server aqlli shartnomaga Invocation tranzaktsiyasini yuboradi (InvocationTx translyatsiyasi). Tranzaksiya shakllangan qaytarib olish funktsiyasiga qo'ng'iroqni o'z ichiga oladi (gameId, rsaSign):

Blockchain-da tasodifiy RSA

Funktsiya o'z ichiga oladi o'yin identifikatori yangi o'yin va shaxsiy kalit bilan noyob identifikatorning RSA imzolanishi natijasi. Imzo natijasi o'zgarmadi.

Bu nimani anglatadi?

Biz bir xil qiymatni (o'yin identifikatori) olamiz va unga RSA imzo usulini qo'llaymiz. Biz har doim bir xil natijaga erishamiz. RSA algoritmi shunday ishlaydi. Yakuniy raqamni manipulyatsiya qilib bo'lmaydi, chunki o'yin identifikatori va RSA qo'llash natijasi noma'lum. Raqamni tanlash ham ma'nosiz.

8. Blokcheyn tranzaksiyani qabul qiladi. U qaytarib olish funksiyasini ishga tushiradi (gameId, rsaSign)

9. Olib tashlash funksiyasi ichida chekinish sodir bo'ladi GenerateRandInt funktsiyalari (o'yin identifikatori, rsaSign). Bu tasodifiy sonlar generatoridir

# @return 1 ... 100
func GenerateRandInt (gameId,rsaSign) = {
   	# verify RSA signature to proof random
    let rsaSigValid = rsaVerify (SHA256, toBytes(gameId), rsaSign, RSAPUBLIC)
    if (rsaSigValid)
        then {
            let rand = (toInt(sha256(rsaSign)) % 100)
            if ((0 > rand))
                then ((-1 * rand) + 1)
                else (rand + 1)
            }
        else throw ("Invalid RSA signature")
    }

rand - va tasodifiy raqam mavjud.

Birinchidan, satr olinadi, bu RSA imzosining natijasidir o'yin identifikatori shaxsiy kalit (rsaSign). Keyin SHA-256 bilan xeshlangan (sha256(rsaSign)).

Imzo va keyingi xeshlash natijasini oldindan aytib bo'lmaydi. Shuning uchun tasodifiy sonni yaratishga ta'sir qilish mumkin emas. Raqamni ma'lum diapazonda (masalan, 1 dan 100 gacha) olish uchun toInt o'zgartirish funksiyasidan va %100 (o'xshash) dan foydalaning. mod).

Maqolaning boshida biz funktsiyani eslatib o'tdik rsaVerify(), bu sizga RSA imzosining haqiqiyligini ochiq kalitga nisbatan shaxsiy kalit yordamida tekshirish imkonini beradi. Mana GenerateRandInt(gameId,rsaSign) qismi:

rsaVerify (SHA256, toBytes(gameId), rsaSign, RSAPUBLIC)

RSAPUBLIC ochiq kaliti va rsaSign satri kirishga uzatiladi. Imzo haqiqiyligi tekshiriladi. Agar tekshirish muvaffaqiyatli bo'lsa, raqam yaratiladi. Aks holda, tizim imzo haqiqiy emas deb hisoblaydi (Invalid RSA signature).

Server shaxsiy kalit bilan o'yin identifikatoriga imzo chekishi va 2880 blok ichida haqiqiy Rsa imzosini yuborishi kerak. Parametr aqlli shartnomani o'rnatishda sozlanadi. Belgilangan vaqt ichida hech narsa sodir bo'lmasa, foydalanuvchi g'alaba qozonadi. Bunday holda, sovrin o'z manzilingizga yuborilishi kerak. Ma'lum bo'lishicha, "serverni aldash foydali emas", chunki bu yo'qotishga olib keladi. Quyida misol keltirilgan.

Blockchain-da tasodifiy RSA

Foydalanuvchi oʻynayapti Zar roliki. Men kubning 2 tomonidan 6 tasini tanladim, garov 14 TO'LQIN. Agar server belgilangan vaqt ichida (2880 blok) aqlli shartnomaga yaroqli RSA imzosini yubormasa, foydalanuvchi 34.44 WAVES oladi.

O'yinlarda raqamlarni yaratish uchun biz oracle-dan foydalanamiz - tashqi, blokcheyn bo'lmagan tizim. Server o'yin identifikatorining RSA imzosini bajaradi. Aqlli shartnoma imzoning haqiqiyligini tekshiradi va g'olibni aniqlaydi. Agar server hech narsa yubormasa, foydalanuvchi avtomatik ravishda g'alaba qozonadi.

Bu halol avlod usuli, chunki manipulyatsiya texnik jihatdan mumkin emas. Barcha Tradisys o'yinlari tasvirlangan algoritm asosida ishlaydi. Blockchain o'yinlari shunday ishlaydi. Hamma narsa shaffof va tekshirilishi mumkin. Boshqa blokcheynlarda bunday tizimning o'xshashlari yo'q. Bu adolatli tasodif.

Manba: www.habr.com

a Izoh qo'shish