RSA ewekansig op blockchain

Daar is 'n probleem - dit is moeilik om 'n ewekansige getal in 'n gedesentraliseerde netwerk te genereer. Byna alle blokkettings het dit al teëgekom. Inderdaad, in netwerke waar daar geen vertroue tussen gebruikers is nie, los die skep van 'n onmiskenbare ewekansige getal baie probleme op.

In hierdie artikel vertel ons jou hoe ons daarin geslaag het om die probleem op te los deur speletjies as voorbeeld te gebruik. Die eerste van hulle was Golwe Kersboom. Vir ontwikkeling het ons 'n ewekansige getalgenerator nodig gehad.

RSA ewekansig op blockchain

Aanvanklik het ons beplan om 'n nommer te genereer gebaseer op inligting van die blokketting. Toe word dit egter duidelik: die nommer kan gemanipuleer word, wat beteken dat die oplossing nie geskik is nie.

Ons het met 'n oplossing vorendag gekom: gebruik die commit-expand-skema. Die bediener het 'n getal van 1 tot 5 geraai, 'n sout daarby gevoeg en dan die resultaat gehash met behulp van Keccak funksies. Die bediener het die slimkontrak met die reeds gestoorde nommer vooraf ontplooi. Dit blyk dat die speletjie daarop neerkom dat die gebruiker die nommer wat deur die hash versteek is, raai.

Die speler het 'n weddenskap geplaas, en die bediener het die verborge nommer en "sout" na die slim kontrak gestuur. In eenvoudige terme het hy die kaarte onthul. Daarna het die bediener die nommers nagegaan en besluit of die gebruiker gewen of verloor het.

As die bediener nie 'n nommer of "sout" vir verifikasie gestuur het nie, het die gebruiker gewen. In hierdie geval was dit vir elke wedstryd nodig om vooraf 'n slim kontrak te ontplooi en potensiële winste daarin in te sluit. Dit blyk ongerieflik, tydrowend en duur te wees. Op daardie stadium was daar geen ander veilige oplossing nie.

Onlangs het die Tradisys-span voorgestel om 'n funksie by die Waves-protokol te voeg rsaVerifieer(). Dit kontroleer die geldigheid van die RSA-handtekening gebaseer op die publieke en private sleutel. As gevolg hiervan is die kenmerk bygevoeg.

Ons het drie speletjies ontwikkel: Sê Roller, Muntflip и Ry Op Golwe. Elkeen implementeer ewekansige getaltegnologie. Kom ons vind uit hoe dit werk.

RSA ewekansig op blockchain

Kom ons kyk na die generering van 'n ewekansige getal deur Ride on Waves as 'n voorbeeld te gebruik. Die slim kontrak kan gevind word hier.

Gaan na die blad Script en kies Gedekompileer. Jy sal die slimkontrakkode (ook bekend as script) sien.

RSA ewekansig op blockchain

Die slimkontrakkode bevat 'n stel funksies. Diegene wat as @Oproepbaar gemerk is, kan begin word deur Oproeptransaksies. Ons stel belang in twee funksies: wed и onttrek:

  • func weddenskap (spelerkeuse)
  • func onttrek(gameId,rsaSign)

1. Die gebruiker kies die lengte van die segment en die weddenskapgrootte.

RSA ewekansig op blockchain

2. Die kliënt skep 'n weddenskapfunksie. Vir die beeld hierbo sou dit wees weddenskap("50").

3. Die kliënt stuur 'n Invocation-transaksie na die slimkontrakadres (broadcast InvocationTx). Die transaksie bevat die weddenskapfunksie as 'n oproepparameter. Dit beteken dat die Invocation-transaksie die uitvoering van die weddenskapfunksie (keuse: String) op die slim kontrak aktiveer.

RSA ewekansig op blockchain

4. Oorweeg die weddenskapfunksie:

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

Die funksie skryf 'n nuwe speletjie na die toestand van die slim kontrak. Naamlik:

  • Unieke identifiseerder vir 'n nuwe speletjie (speletjie-ID)
  • Speltoestand = INGEDIEN
  • Speler se keuse (segmentlengte 50)
  • Publieke sleutel
  • Potensiële winste (afhangende van die speler se weddenskap)

RSA ewekansig op blockchain

Dit is hoe 'n datarekord in die blokketting lyk (sleutelwaarde):

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

"Sleutel" (sleutel) - spel ID nuwe spel. Die oorblywende data is vervat in die reël van die "waarde"-veld. Hierdie inskrywings word in die oortjie gestoor data slim kontrak:

RSA ewekansig op blockchain

RSA ewekansig op blockchain

5. Die bediener "kyk" na die slim kontrak en vind die gestuurde transaksie (nuwe speletjie) met behulp van die blokketting Api. Die speletjie-ID van die nuwe speletjie is reeds in die blokketting aangeteken, wat beteken dat dit nie meer verander of beïnvloed kan word nie

6. Die bediener genereer 'n onttrekfunksie (gameId, rsaSign). Byvoorbeeld, soos volg:

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

7. Die bediener stuur 'n Invocation-transaksie na die slimkontrak (broadcast InvocationTx). Die transaksie bevat 'n oproep na die gevormde onttrekkingsfunksie (gameId, rsaSign):

RSA ewekansig op blockchain

Die funksie bevat spel ID nuwe speletjie en die resultaat van RSA-ondertekening van 'n unieke identifiseerder met 'n private sleutel. Die handtekeningresultaat is onveranderd.

Wat beteken dit?

Ons neem dieselfde waarde (speletjie-ID) en pas die RSA-handtekeningmetode daarop toe. Ons sal altyd dieselfde resultaat kry. Dit is hoe die RSA-algoritme werk. Die finale nommer kan nie gemanipuleer word nie, aangesien die spel-ID en die resultaat van die toepassing van RSA nie bekend is nie. Om 'n nommer te kies is ook nutteloos.

8. Blockchain aanvaar die transaksie. Dit loop die onttrek-funksie (gameId, rsaSign)

9. Binne die onttrekkingsfunksie vind onttrekking plaas GenerateRandInt funksies (gameId, rsaSign). Dit is 'n ewekansige getalgenerator

# @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 - en daar is 'n ewekansige getal.

Eerstens word die tou geneem, wat die resultaat is van die RSA-handtekening spel ID privaat sleutel (rsaTeken). Dan verhak met SHA-256 (sha256(rsaSign)).

Ons kan nie die uitkoms van die handtekening en daaropvolgende hashing voorspel nie. Daarom is dit onmoontlik om die generering van 'n ewekansige getal te beïnvloed. Om 'n getal in 'n sekere reeks te kry (byvoorbeeld van 1 tot 100), gebruik die toInt-omskakelingsfunksie en %100 (soortgelyk aan mod).

Aan die begin van die artikel het ons die funksie genoem rsaVerifieer(), wat jou toelaat om die geldigheid van 'n RSA-handtekening te kontroleer met 'n private sleutel teenoor 'n publieke een. Hier is die GenerateRandInt(gameId,rsaSign) deel:

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

Die publieke sleutel RSAPUBLIC en die rsaSign-string word na die invoer deurgegee. Die handtekening word gekontroleer vir geldigheid. Die nommer word gegenereer as die tjek suksesvol is. Andersins is die stelsel van mening dat die handtekening nie geldig is nie (Ongeldige RSA handtekening).

Die bediener moet die speletjie-ID met 'n private sleutel onderteken en 'n geldige Rsa-handtekening binne 2880 blokke stuur. Die parameter word opgestel wanneer die slimkontrak ontplooi word. As niks binne die toegelate tyd gebeur nie, wen die gebruiker. In hierdie geval moet die prys self na jou adres gestuur word. Dit blyk dat dit "nie winsgewend is vir die bediener om te kul nie", want dit lei tot verlies. Hieronder is 'n voorbeeld.

RSA ewekansig op blockchain

Die gebruiker speel Sê Roller. Ek het 2 van die 6 kante van die kubus gekies, die weddenskap is 14 GOLWE. As die bediener nie binne die gespesifiseerde tyd (2880 blokke) 'n geldige RSA-handtekening na die slimkontrak stuur nie, sal die gebruiker 34.44 GOLWE neem.

Om getalle in speletjies te genereer, gebruik ons ​​'n orakel - 'n eksterne, nie-blokkettingstelsel. Die bediener voer 'n RSA-handtekening van die speletjie-ID uit. Die slim kontrak kontroleer die geldigheid van die handtekening en bepaal die wenner. As die bediener niks stuur nie, wen die gebruiker outomaties.

Dit is 'n eerlike generasie metode, want manipulasie is tegnies onmoontlik. Alle Tradisys-speletjies werk gebaseer op die beskryfde algoritme. Dit is hoe blockchain-speletjies werk. Alles is deursigtig en verifieerbaar. Daar is geen analoë van so 'n stelsel in enige ander blokketting nie. Dit is 'n redelike toeval.

Bron: will.com

Voeg 'n opmerking