RSA hazarda sur blokĉeno

Estas problemo - estas malfacile generi hazardan nombron en malcentralizita reto. Preskaŭ ĉiuj blokĉenoj jam renkontis ĉi tion. Efektive, en retoj, kie ne ekzistas fido inter uzantoj, krei nekontesteblan hazardan nombron solvas multajn problemojn.

En ĉi tiu artikolo ni rakontas al vi kiel ni sukcesis solvi la problemon uzante ludojn kiel ekzemplon. La unua el ili estis Ondoj Kristnaska Arbo. Por evoluo, ni bezonis hazardan nombrogeneratoron.

RSA hazarda sur blokĉeno

Komence, ni planis generi nombron bazitan sur informoj de la blokĉeno. Tamen, tiam evidentiĝis: la nombro povus esti manipulita, kio signifas, ke la solvo ne taŭgas.

Ni elpensis solvon: uzu la kommit-expand-skemon. La servilo divenis nombron de 1 ĝis 5, aldonis salon al ĝi, kaj poste hakis la rezulton uzante Keccak-funkcioj. La servilo deplojis la inteligentan kontrakton kun la jam konservita nombro anticipe. Rezultas, ke la ludo resumas, ke la uzanto divenas la nombron kaŝitan de la hash.

La ludanto metis veton, kaj la servilo sendis la kaŝitan nombron kaj "salon" al la inteligenta kontrakto. En simplaj esprimoj, li rivelis la kartojn. Post tio, la servilo kontrolis la nombrojn kaj decidis ĉu la uzanto venkis aŭ perdis.

Se la servilo ne sendis numeron aŭ "salon" por konfirmo, la uzanto venkis. En ĉi tiu kazo, por ĉiu ludo estis necese deploji inteligentan kontrakton anticipe kaj inkluzivi eblajn gajnojn en ĝi. Ĝi montriĝis maloportuna, tempopostula kaj multekosta. Tiutempe ne estis alia sekura solvo.

Lastatempe, la teamo de Tradisys proponis aldoni funkcion al la protokolo Waves rsaVerify (). Ĝi kontrolas la validecon de la RSA-signaturo bazita sur la publika kaj privata ŝlosilo. Kiel rezulto, la funkcio estis aldonita.

Ni evoluigis tri ludojn: Diras Roller, Monero Flip и Rajdu Sur Ondoj. Ĉiu efektivigas hazardan nombroteknologion. Ni eltrovu kiel ĝi funkcias.

RSA hazarda sur blokĉeno

Ni rigardu generi hazardan nombron uzante Ride on Waves kiel ekzemplon. La inteligenta kontrakto troveblas tie.

Iru al la langeto skripto kaj elektu Malkompilita. Vi vidos la inteligentan kontraktokodon (alinome skripto).

RSA hazarda sur blokĉeno

La inteligenta kontraktokodo enhavas aron da funkcioj. Tiuj markitaj kiel @Callable povas esti lanĉitaj uzante Alvoko-transakcioj. Ni interesiĝas pri du funkcioj: veto и retiri:

  • func veto (ludantoElekto)
  • func retiro(gameId,rsaSign)

1. La uzanto elektas la longon de la segmento kaj la vetan grandecon.

RSA hazarda sur blokĉeno

2. La kliento kreas vetan funkcion. Por la supra bildo estus veto ("50").

3. La kliento sendas Invocation-transakcion al la inteligenta kontrakto-adreso (elsendo InvocationTx). La transakcio enhavas la vetan funkcion kiel voka parametro. Ĉi tio signifas, ke la transakcio de Alvoko ekigas la ekzekuton de la veta funkcio (elekto: Ŝnuro) sur la inteligenta kontrakto.

RSA hazarda sur blokĉeno

4. Konsideru la vetan funkcion:

@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)))
                    }
    }

La funkcio skribas novan ludon al la stato de la inteligenta kontrakto. Nome:

  • Unika identigilo por nova ludo (identigilo de la ludo)
  • Ludstato = SUBMITITA
  • La elekto de ludanto (segmentlongo 50)
  • Publika ŝlosilo
  • Eblaj gajnoj (depende de la veto de la ludanto)

RSA hazarda sur blokĉeno

Jen kiel aspektas datuma rekordo en la blokĉeno (ŝlosilvaloro):

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

"Ŝlosilo" (ŝlosilo) - ludo-identigilo nova ludo. La ceteraj datumoj estas enhavitaj en la linio de la kampo "valora". Ĉi tiuj enskriboj estas konservitaj en la langeto datumoj inteligenta kontrakto:

RSA hazarda sur blokĉeno

RSA hazarda sur blokĉeno

5. La servilo "rigardas" la inteligentan kontrakton kaj trovas la senditan transakcion (novan ludon) uzante la blokĉenon Api. La Ludidentigilo de la nova ludo jam estas registrita en la blokĉeno, kio signifas, ke ĝi ne plu povas esti ŝanĝita aŭ influita.

6. La servilo generas retiriĝan funkcion (gameId, rsaSign). Ekzemple, tiel:

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

7. La servilo sendas Invocation-transakcion al la inteligenta kontrakto (elsendo InvocationTx). La transakcio enhavas vokon al la formita retiriĝa funkcio (gameId, rsaSign):

RSA hazarda sur blokĉeno

La funkcio enhavas ludo-identigilo nova ludo kaj la rezulto de RSA subskribo de unika identigilo kun privata ŝlosilo. La subskriba rezulto estas senŝanĝa.

Kion tio signifas?

Ni prenas la saman valoron (ludo-identigilo) kaj aplikas la RSA subskriban metodon al ĝi. Ni ĉiam ricevos la saman rezulton. Tiel funkcias la RSA-algoritmo. La fina nombro ne povas esti manipulita, ĉar la ludidentigilo kaj la rezulto de aplikado de RSA ne estas konataj. Elekti nombron ankaŭ estas sencela.

8. Blockchain akceptas la transakcion. Ĝi rulas la retiriĝan funkcion (gameId, rsaSign)

9. Ene de la retiriĝa funkcio okazas retiriĝo GenerateRandInt-funkcioj (gameId, rsaSign). Ĉi tio estas hazarda nombrogeneratoro

# @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 - kaj estas hazarda nombro.

Unue, la ŝnuro estas prenita, kio estas la rezulto de la RSA-signaturo ludo-identigilo privata ŝlosilo (rsaSign). Poste hakis kun SHA-256 (sha256(rsaSign)).

Ni ne povas antaŭdiri la rezulton de la subskribo kaj posta hashing. Tial, estas neeble influi la generacion de hazarda nombro. Por akiri nombron en certa intervalo (ekzemple, de 1 ĝis 100), uzu la konvertan funkcion toInt kaj % 100 (simila al mod).

Komence de la artikolo ni menciis la funkcion rsaVerify (), kiu permesas kontroli la validecon de RSA subskribo uzante privatan ŝlosilon kontraŭ publika. Jen la parto GenerateRandInt(gameId,rsaSign):

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

La publika ŝlosilo RSAPUBLIC kaj la rsaSign-ĉeno estas transdonitaj al la enigo. La subskribo estas kontrolita por valideco. La nombro estas generita se la kontrolo estas sukcesa. Alie, la sistemo konsideras, ke la subskribo ne validas (Nevalida RSA-signaturo).

La servilo devas subskribi la ludidentigilon per privata ŝlosilo kaj sendi validan Rsa subskribon ene de 2880 blokoj. La parametro estas agordita dum deplojado de la inteligenta kontrakto. Se nenio okazas en la asignita tempo, la uzanto gajnas. En ĉi tiu kazo, la premio devas esti sendita mem al via adreso. Rezultas, ke "ne estas profita por la servilo trompi", ĉar ĉi tio kondukas al perdo. Malsupre estas ekzemplo.

RSA hazarda sur blokĉeno

La uzanto ludas Diras Roller. Mi elektis 2 el la 6 flankoj de la kubo, la veto estas 14 ONDOJ. Se la servilo ne sendas validan RSA subskribon al la inteligenta kontrakto ene de la specifita tempo (2880 blokoj), la uzanto prenos 34.44 ONDAS.

Por generi nombrojn en ludoj, ni uzas orakolon - eksteran, ne-blokan sistemon. La servilo elfaras RSA subskribon de la ludidentigilo. La inteligenta kontrakto kontrolas la validecon de la subskribo kaj determinas la gajninton. Se la servilo sendas nenion, tiam la uzanto aŭtomate gajnas.

Ĉi tio estas honesta genera metodo, ĉar manipulado estas teknike neebla. Ĉiuj Tradisys-ludoj funkcias surbaze de la priskribita algoritmo. Tiel funkcias blokĉenaj ludoj. Ĉio estas travidebla kaj kontrolebla. Ne ekzistas analogoj de tia sistemo en iu ajn alia blokĉeno. Ĉi tio estas justa hazarda.

fonto: www.habr.com

Aldoni komenton