RSA willekeurich op blockchain

D'r is in probleem - it is lestich om in willekeurige nûmer te generearjen yn in desintralisearre netwurk. Hast alle blockchains hawwe dit al tsjinkaam. Yndied, yn netwurken wêr't gjin fertrouwen tusken brûkers is, it meitsjen fan in ûnbestriden willekeurich nûmer lost in protte problemen op.

Yn dit artikel fertelle wy jo hoe't wy it probleem hawwe oplost mei spultsjes as foarbyld. De earste fan harren wie Waves Xmas Tree. Foar ûntwikkeling hawwe wy in willekeurige getalgenerator nedich.

RSA willekeurich op blockchain

Yn it earstoan planden wy in nûmer te generearjen op basis fan ynformaasje fan 'e blockchain. Lykwols, doe waard dúdlik: it oantal koe wurde manipulearre, dat betsjut dat de oplossing is net geskikt.

Wy kamen mei in oplossing: brûk it commit-expand-skema. De tsjinner riede in nûmer fan 1 oan 5, tafoege in sâlt oan it, en dan hashed it resultaat mei help Keccak funksjes. De tsjinner ynset it tûke kontrakt mei it al opsleine nûmer foarôf. It docht bliken dat it spultsje delkomt op 'e brûker dy't it oantal ferburgen troch de hash riedt.

De spiler pleatst in weddenskip, en de tsjinner stjoerde it ferburgen nûmer en "sâlt" nei de smart kontrakt. Yn ienfâldige termen iepenbiere hy de kaarten. Dêrnei kontrolearre de tsjinner de nûmers en besletten oft de brûker wûn of ferlern.

As de tsjinner gjin nûmer of "sâlt" stjoerde foar ferifikaasje, wûn de brûker. Yn dit gefal, foar eltse wedstriid wie it nedich om te ynsetten in tûk kontrakt foarôf en befetsje potinsjele winsten yn it. It die bliken ûngemaklik, tiidslinend en djoer. Op dat stuit wie der gjin oare feilige oplossing.

Koartlyn stelde it Tradisys-team foar om in funksje ta te foegjen oan it Waves-protokol rsaVerify(). It kontrolearret de jildigens fan 'e RSA-hântekening basearre op de publike en privee kaai. As gefolch waard de funksje tafoege.

Wy hawwe trije spultsjes ûntwikkele: Dice Roller, Coin Flip и Ride Op Weagen. Elk implementeart willekeurige nûmertechnology. Litte wy útfine hoe't it wurket.

RSA willekeurich op blockchain

Litte wy sjen nei it generearjen fan in willekeurich nûmer mei Ride on Waves as foarbyld. It tûke kontrakt is te finen hjir.

Gean nei it ljepper Skrift en selektearje Dekompilearre. Jo sille de tûke kontraktkoade (aka skript) sjen.

RSA willekeurich op blockchain

De smart kontraktkoade befettet in set fan funksjes. Dy markearre as @Callable kinne wurde lansearre mei help Invocation transaksjes. Wy binne ynteressearre yn twa funksjes: weddenskip и weromlûke:

  • func bet (playerChoice)
  • func weromlûke (gameId, rsaSign)

1. De brûker selektearret de lingte fan it segmint en de weddenskip grutte.

RSA willekeurich op blockchain

2. De klant makket in weddenskip funksje. Foar de ôfbylding hjirboppe soe it wêze bet("50").

3. De kliïnt stjoert in Invocation-transaksje nei it smart kontraktadres (útstjoering InvocationTx). De transaksje befettet de weddenskip funksje as oprop parameter. Dit betsjut dat de Invocation-transaksje de útfiering fan 'e weddenskipfunksje triggert (kar: String) op it smart kontrakt.

RSA willekeurich op blockchain

4. Betink de weddenskip funksje:

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

De funksje skriuwt in nij spultsje oan 'e steat fan' e smart kontrakt. Nammentlik:

  • Unike identifier foar in nij spultsje (spultsje id)
  • Spultsje steat = Yntsjinne
  • Spiler's kar (segmint lingte 50)
  • Iepenbiere kaai
  • Potinsjele winsten (ôfhinklik fan de weddenskip fan de spiler)

RSA willekeurich op blockchain

Dit is hoe in gegevensrecord yn 'e blockchain derút sjocht (kaai-wearde):

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

"Kaai" (kaai) - spultsje id nij spultsje. De oerbleaune gegevens binne befette yn 'e line fan it fjild "wearde". Dizze yngongen wurde opslein yn 'e ljepper Data smart kontrakt:

RSA willekeurich op blockchain

RSA willekeurich op blockchain

5. De tsjinner "sjocht" nei it tûke kontrakt en fynt de ferstjoerde transaksje (nij spultsje) mei de blockchain Api. De Game id fan it nije spultsje is al opnommen yn 'e blockchain, wat betsjut dat it net mear kin wurde feroare of beynfloede

6. De tsjinner genereart in weromlûken funksje (gameId, rsaSign). Bygelyks, lykas dit:

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

7. De tsjinner stjoert in Invocation transaksje nei de smart kontrakt (útstjoering InvocationTx). De transaksje befettet in oprop nei de foarme weromlûkfunksje (gameId, rsaSign):

RSA willekeurich op blockchain

De funksje befettet spultsje id nij spultsje en it resultaat fan RSA ûndertekening fan in unike identifier mei in privee kaai. It resultaat fan 'e hantekening is net feroare.

Wat betsjut dit?

Wy nimme deselde wearde (spultsje id) en tapasse de RSA-hântekeningmetoade derop. Wy sille altyd itselde resultaat krije. Dit is hoe't it RSA-algoritme wurket. It definitive nûmer kin net manipulearre wurde, om't it spultsje-ID en it resultaat fan it tapassen fan RSA net bekend binne. In nûmer kieze is ek nutteloos.

8. Blockchain akseptearret de transaksje. It rint de weromlûkfunksje (gameId, rsaSign)

9. Binnen de weromlûken funksje komt weromlûken GenerateRandInt funksjes (gameId, rsaSign). Dit is in willekeurige getallengenerator

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

rûn - en der is in willekeurich getal.

Earst wurdt de tekenrige nommen, wat it resultaat is fan 'e RSA-hântekening spultsje id privee kaai (rsaSign). Dan hashed mei SHA-256 (sha256(rsaSign)).

Wy kinne de útkomst fan 'e hantekening en de folgjende hashing net foarsizze. Dêrom is it ûnmooglik om de generaasje fan in willekeurich getal te beynfloedzjen. Om in nûmer yn in bepaald berik te krijen (bygelyks fan 1 oant 100), brûk dan de konverzjefunksje toInt en % 100 (lykas mod).

Oan it begjin fan it artikel hawwe wy de funksje neamd rsaVerify(), wêrtroch jo de jildichheid fan in RSA-hântekening kinne kontrolearje mei in privee kaai tsjin in iepenbiere. Hjir is it GenerateRandInt(gameId,rsaSign) diel:

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

De iepenbiere kaai RSAPUBLIC en de rsaSign tekenrige wurde trochjûn oan de ynfier. De hantekening wurdt kontrolearre op jildichheid. It nûmer wurdt oanmakke as de kontrôle suksesfol is. Oars, it systeem fynt dat de hântekening is net jildich (Unjildige RSA hântekening).

De tsjinner moat tekenje it spultsje id mei in privee kaai en stjoer in jildich Rsa hântekening binnen 2880 blokken. De parameter is konfigureare by it ynsetten fan it smart kontrakt. As der neat bart binnen de tawiisde tiid, wint de brûker. Yn dit gefal moat de priis sels nei jo adres stjoerd wurde. It docht bliken dat it "net rendabel is foar de tsjinner om te ferrifeljen", om't dit liedt ta ferlies. Hjirûnder is in foarbyld.

RSA willekeurich op blockchain

De brûker spilet Dice Roller. Ik keas 2 fan de 6 kanten fan de kubus, de weddenskip is 14 WAVES. As de tsjinner gjin jildige RSA-hântekening stjoert nei it tûke kontrakt binnen de opjûne tiid (2880 blokken), sil de brûker 34.44 WAVES nimme.

Om sifers yn spultsjes te generearjen, brûke wy in orakel - in ekstern, net-blockchain-systeem. De tsjinner fiert in RSA-hântekening fan it spultsje id. It tûke kontrakt kontrolearret de jildigens fan 'e hantekening en bepaalt de winner. As de tsjinner neat ferstjoert, dan wint de brûker automatysk.

Dit is in earlike generaasjemetoade, om't manipulaasje technysk ûnmooglik is. Alle Tradisys games wurkje basearre op de beskreaune algoritme. Dit is hoe't blockchain-spultsjes wurkje. Alles is transparant en kontrolearber. D'r binne gjin analogen fan sa'n systeem yn in oare blockchain. Dit is in earlike willekeurich.

Boarne: www.habr.com

Add a comment