Vyskytol sa problém – v decentralizovanej sieti je ťažké vygenerovať náhodné číslo. Stretli sa s tým už takmer všetky blockchainy. V sieťach, kde medzi používateľmi neexistuje dôvera, vytvorenie nepopierateľného náhodného čísla rieši veľa problémov.
V tomto článku vám povieme, ako sa nám podarilo vyriešiť problém pomocou hier ako príkladu. Prvý z nich bol
Pôvodne sme plánovali vygenerovať číslo na základe informácií z blockchainu. Potom však bolo jasné: s číslom sa dalo manipulovať, čo znamená, že riešenie nie je vhodné.
Prišli sme s riešením: použite schému commit-expand. Server uhádol číslo od 1 do 5, pridal k nemu soľ a potom výsledok hashoval pomocou
Hráč uzavrel stávku a server poslal skryté číslo a „soľ“ do inteligentnej zmluvy. Jednoducho povedané, odhalil karty. Potom server skontroloval čísla a rozhodol, či používateľ vyhral alebo prehral.
Ak server neposlal číslo alebo „soľ“ na overenie, používateľ vyhral. V tomto prípade bolo pre každú hru potrebné vopred nasadiť smart kontrakt a zahrnúť do neho prípadné výhry. Ukázalo sa, že je to nepohodlné, časovo náročné a drahé. V tom čase neexistovalo iné bezpečné riešenie.
Nedávno tím Tradisys navrhol pridanie funkcie do protokolu Waves rsaVerify(). Kontroluje platnosť RSA podpisu na základe verejného a súkromného kľúča. V dôsledku toho bola funkcia pridaná.
Vyvinuli sme tri hry:
Pozrime sa na generovanie náhodného čísla pomocou príkladu Ride on Waves. Inteligentná zmluva sa dá nájsť
Prejdite na kartu Skript a vyberte Dekompilovaný. Uvidíte kód inteligentnej zmluvy (aka skript).
Kód inteligentnej zmluvy obsahuje súbor funkcií. Tie označené ako @Callable je možné spustiť pomocou Vyvolávacie transakcie. Zaujímajú nás dve funkcie: stávka и ustúpiť:
- func bet (playerChoice)
- func draw(gameId,rsaSign)
1. Používateľ si vyberie dĺžku segmentu a veľkosť stávky.
2. Klient vytvorí stávkovú funkciu. Pre obrázok vyššie by to bolo stávka ("50").
3. Klient odošle transakciu Invocation na adresu smart kontraktu (broadcast InvocationTx). Transakcia obsahuje funkciu stávky ako parameter call. To znamená, že transakcia vyvolania spúšťa spustenie funkcie stávky (výber: String) na smart kontrakte.
4. Zvážte funkciu stávky:
@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)))
}
}
Funkcia zapíše novú hru do stavu smart kontraktu. menovite:
- Jedinečný identifikátor pre novú hru (identifikátor hry)
- Stav hry = ODOSLANÉ
- Výber hráča (dĺžka segmentu 50)
- Verejný kľúč
- Potenciálne výhry (v závislosti od stávky hráča)
Takto vyzerá dátový záznam v blockchaine (kľúč – hodnota):
{
"type": "string",
"value": "03WON_0283_448t8Jn9P3717UnXFEVD5VWjfeGE5gBNeWg58H2aJeQEgJ_06574069_09116020000_0229",
"key": "2GKTX6NLTgUrE4iy9HtpSSHpZ3G8W4cMfdjyvvnc21dx"
}
"Kľúč" (kľúč) - id hry Nová hra. Zostávajúce údaje sú obsiahnuté v riadku poľa „hodnota“. Tieto záznamy sú uložené na karte dátum inteligentná zmluva:
5. Server sa „pozrie“ na smart kontrakt a nájde odoslanú transakciu (novú hru) pomocou blockchain Api. Herné ID novej hry je už zaznamenané v blockchaine, čo znamená, že ho už nemožno zmeniť ani ovplyvniť
6. Server vygeneruje funkciu stiahnutia (gameId, rsaSign). Napríklad takto:
withdraw ("FwsuaaShC6DMWdSWQ5osGWtYkVbTEZrsnxqDbVx5oUpq", "base64:Gy69dKdmXUEsAmUrpoWxDLTQOGj5/qO8COA+QjyPVYTAjxXYvEESJbSiCSBRRCOAliqCWwaS161nWqoTL/TltiIvw3nKyd4RJIBNSIgEWGM1tEtNwwnRwSVHs7ToNfZ2Dvk/GgPUqLFDSjnRQpTHdHUPj9mQ8erWw0r6cJXrzfcagKg3yY/0wJ6AyIrflR35mUCK4cO7KumdvC9Mx0hr/ojlHhN732nuG8ps4CUlRw3CkNjNIajBUlyKQwpBKmmiy3yJa/QM5PLxqdppmfFS9y0sxgSlfLOgZ51xRDYuS8NViOA7c1JssH48ZtDbBT5yqzRJXs3RnmZcMDr/q0x6Bg==")
7. Server odošle transakciu Invocation do smart kontraktu (broadcast InvocationTx). Transakcia obsahuje volanie vytvorenej funkcie výberu (gameId, rsaSign):
Funkcia obsahuje id hry nová hra a výsledok RSA podpísania jedinečného identifikátora privátnym kľúčom. Výsledok podpisu sa nemení.
Čo to znamená?
Vezmeme rovnakú hodnotu (identifikátor hry) a aplikujeme na ňu metódu podpisu RSA. Vždy dostaneme rovnaký výsledok. Takto funguje algoritmus RSA. S konečným číslom nemožno manipulovať, pretože nie je známe ID hry ani výsledok aplikácie RSA. Výber čísla je tiež zbytočný.
8. Blockchain akceptuje transakciu. Spúšťa funkciu stiahnutia (gameId, rsaSign)
9. Vo vnútri funkcie stiahnutia dôjde k stiahnutiu Funkcie GenerateRandInt (gameId, rsaSign). Toto je generátor náhodných čísel
# @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 - a je tam náhodné číslo.
Najprv sa vezme reťazec, ktorý je výsledkom podpisu RSA id hry súkromný kľúč (rsaSign). Potom hašovaný pomocou SHA-256 (sha256(rsaSign)).
Nevieme predpovedať výsledok podpisu a následného hashovania. Preto nie je možné ovplyvniť generovanie náhodného čísla. Ak chcete získať číslo v určitom rozsahu (napríklad od 1 do 100), použite funkciu prevodu na toInt a %100 (podobne ako
Na začiatku článku sme spomenuli funkciu rsaVerify(), ktorý umožňuje skontrolovať platnosť RSA podpisu pomocou súkromného kľúča voči verejnému. Tu je časť GenerateRandInt(gameId,rsaSign):
rsaVerify (SHA256, toBytes(gameId), rsaSign, RSAPUBLIC)
Na vstup sa odovzdá verejný kľúč RSAPUBLIC a reťazec rsaSign. Overí sa platnosť podpisu. Číslo sa vygeneruje, ak je kontrola úspešná. V opačnom prípade systém usúdi, že podpis nie je platný (neplatný podpis RSA).
Server musí podpísať ID hry súkromným kľúčom a odoslať platný podpis Rsa do 2880 XNUMX blokov. Parameter sa konfiguruje pri nasadzovaní inteligentnej zmluvy. Ak sa v stanovenom čase nič nestane, používateľ vyhráva. V takom prípade je potrebné výhru poslať na vašu adresu sami. Ukazuje sa, že „pre server nie je výhodné podvádzať“, pretože to vedie k strate. Nižšie je uvedený príklad.
Používateľ hrá
Na generovanie čísel v hrách používame oracle – externý, neblockchainový systém. Server vykoná RSA podpis ID hry. Smart kontrakt skontroluje platnosť podpisu a určí víťaza. Ak server nič nepošle, používateľ automaticky vyhráva.
Ide o poctivú generačnú metódu, pretože manipulácia je technicky nemožná. Všetky hry Tradisys fungujú na základe opísaného algoritmu. Takto fungujú blockchainové hry. Všetko je transparentné a overiteľné. Neexistujú žiadne analógy takéhoto systému v žiadnom inom blockchaine. Toto je riadna náhoda.
Zdroj: hab.com