Aya masalah - hese ngahasilkeun angka acak dina jaringan desentralisasi. Ampir sadaya blockchains parantos mendakan ieu. Mémang, dina jaringan anu teu aya kapercayaan antara pangguna, nyiptakeun nomer acak anu teu tiasa dipungkirkeun ngarengsekeun seueur masalah.
Dina artikel ieu kami ngabejaan ka maneh kumaha urang junun ngajawab masalah ngagunakeun kaulinan sabagé conto. Anu kahiji di antarana éta
Mimitina, urang ngarencanakeun pikeun ngahasilkeun nomer dumasar kana inpormasi tina blockchain. Nanging, teras janten jelas: jumlahna tiasa dimanipulasi, anu hartosna solusina henteu cocog.
Urang datang nepi ka workaround a: make skéma commit-expand. server nebak angka ti 1 nepi ka 5, ditambahkeun uyah ka dinya, lajeng hashed hasilna ngagunakeun
Pamuter nempatkeun bets, sarta server dikirim jumlah disumputkeun na "uyah" kana kontrak pinter. Dina istilah basajan, anjeunna nembongkeun kartu. Saatos éta, server pariksa nomer sareng mutuskeun naha pangguna meunang atanapi éléh.
Upami server henteu ngirimkeun nomer atanapi "uyah" pikeun verifikasi, pangguna meunang. Dina hal ieu, pikeun tiap kaulinan ieu perlu nyebarkeun kontrak pinter sateuacanna tur kaasup poténsi winnings di dinya. Tétéla teu merenah, waktu-consuming jeung mahal. Dina waktos éta teu aya solusi anu sanés anu aman.
Anyar-anyar ieu, tim Tradisys ngusulkeun nambihan fungsi kana protokol Waves rsaVerify(). Éta pariksa validitas tanda tangan RSA dumasar kana konci umum sareng swasta. Hasilna, fitur ieu ditambahkeun.
Kami parantos ngembangkeun tilu kaulinan:
Hayu urang tingali dina ngahasilkeun angka acak ngagunakeun Ride on Waves salaku conto. Kontrak pinter tiasa dipendakan
Pindah ka tab naskah sareng pilih Decompiled. Anjeun bakal ningali kode kontrak pinter (alias naskah).
Kode kontrak pinter ngandung sakumpulan fungsi. Anu ditandaan salaku @Callable tiasa diluncurkeun nganggo Transaksi invocation. Kami museurkeun dua fungsi: tarohan и mundur:
- func bet (playerChoice)
- fungsi mundur(gameId,rsaSign)
1. Pamaké milih panjang ruas jeung ukuran bet.
2. klien nu nyiptakeun fungsi bet. Pikeun gambar di luhur bakal jadi bet ("50").
3. Klien ngirimkeun transaksi Invocation ka alamat kontrak pinter (broadcast InvocationTx). urus ngandung fungsi alungan salaku parameter panggero. Ieu ngandung harti yén transaksi Invocation micu palaksanaan fungsi bet (pilihan: String) dina kontrak pinter.
4. Pertimbangkeun fungsi alungan:
@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)))
}
}
fungsi nulis kaulinan anyar kana kaayaan kontrak pinter. Nyaéta:
- Identifier unik pikeun kaulinan anyar (id kaulinan)
- kaayaan kaulinan = dikintunkeun
- Pilihan pamaén (panjangna ruas 50)
- konci umum
- Poténsi winnings (gumantung kana bet pamuter urang)
Ieu mangrupikeun catetan data dina blockchain (nilai konci):
{
"type": "string",
"value": "03WON_0283_448t8Jn9P3717UnXFEVD5VWjfeGE5gBNeWg58H2aJeQEgJ_06574069_09116020000_0229",
"key": "2GKTX6NLTgUrE4iy9HtpSSHpZ3G8W4cMfdjyvvnc21dx"
}
"Konci" (konci) - id kaulinan kaulinan anyar. Data sésana dikandung dina garis tina widang "nilai". Éntri ieu disimpen dina tab data kontrak pinter:
5. Server "katingal" dina kontrak pinter jeung manggihan transaksi dikirim (kaulinan anyar) ngagunakeun blockchain Api. The Game id tina kaulinan anyar geus kacatet dina blockchain, nu hartina teu bisa deui dirobah atawa dipangaruhan
6. Server ngahasilkeun fungsi mundur (gameId, rsaSign). Contona, saperti kieu:
withdraw ("FwsuaaShC6DMWdSWQ5osGWtYkVbTEZrsnxqDbVx5oUpq", "base64:Gy69dKdmXUEsAmUrpoWxDLTQOGj5/qO8COA+QjyPVYTAjxXYvEESJbSiCSBRRCOAliqCWwaS161nWqoTL/TltiIvw3nKyd4RJIBNSIgEWGM1tEtNwwnRwSVHs7ToNfZ2Dvk/GgPUqLFDSjnRQpTHdHUPj9mQ8erWw0r6cJXrzfcagKg3yY/0wJ6AyIrflR35mUCK4cO7KumdvC9Mx0hr/ojlHhN732nuG8ps4CUlRw3CkNjNIajBUlyKQwpBKmmiy3yJa/QM5PLxqdppmfFS9y0sxgSlfLOgZ51xRDYuS8NViOA7c1JssH48ZtDbBT5yqzRJXs3RnmZcMDr/q0x6Bg==")
7. Server ngirimkeun transaksi Invocation ka kontrak pinter (siaran InvocationTx). Transaksi ngandung sauran kana fungsi mundur anu dibentuk (gameId, rsaSign):
fungsi nu ngandung id kaulinan kaulinan anyar jeung hasil tina RSA Signing of a identifier unik kalayan konci swasta. Hasil tanda tangan henteu robih.
Naon eta hartosna?
Kami nyandak nilai anu sami (id kaulinan) sareng nerapkeun metode tanda tangan RSA. Kami bakal salawasna nampi hasil anu sami. Ieu kumaha algoritma RSA jalan. Jumlah ahir teu bisa dimanipulasi, saprak id kaulinan sarta hasil panawaran RSA teu dipikawanoh. Milih nomer ogé henteu aya gunana.
8. Blockchain narima transaksi. Éta ngajalankeun fungsi mundur (gameId, rsaSign)
9. Jero fungsi ditarikna, ditarikna lumangsung GenerateRandInt fungsi (gameId, rsaSign). Ieu generator angka acak
# @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 - tur aya angka acak.
Kahiji, string dicokot, nu mangrupa hasil tina tanda tangan RSA id kaulinan konci pribadi (rsaSign). Teras hashed sareng SHA-256 (sha256(rsaSign)).
Kami henteu tiasa ngaduga hasil tina tandatangan sareng hashing salajengna. Ku alatan éta, teu mungkin pangaruh generasi angka acak. Pikeun meunangkeun angka dina rentang nu tangtu (contona, ti 1 nepi ka 100), paké pungsi konversi toInt jeung %100 (sarupa jeung
Dina awal artikel kami disebutkeun fungsi rsaVerify(), anu ngamungkinkeun anjeun mariksa validitas tanda tangan RSA nganggo konci pribadi ngalawan konci umum. Ieu bagian GenerateRandInt(gameId,rsaSign):
rsaVerify (SHA256, toBytes(gameId), rsaSign, RSAPUBLIC)
Konci publik RSAPUBLIC sareng senar rsaSign dialihkeun kana input. Signature dipariksa pikeun validitas. Jumlahna dihasilkeun lamun cék suksés. Upami teu kitu, sistem nganggap yén tanda tangan henteu sah (tanda tangan RSA teu valid).
server kudu asup id kaulinan kalayan konci swasta sarta ngirimkeun tanda tangan Rsa valid dina 2880 blok. Parameter dikonpigurasi nalika nyebarkeun kontrak pinter. Lamun euweuh kajadian dina waktu allotted, pamaké meunang. Dina hal ieu, hadiah kudu dikirim ka alamat anjeun sorangan. Tétéla éta "teu nguntungkeun pikeun server curang", sabab ieu ngakibatkeun leungitna. Di handap ieu conto.
pamaké éta maén
Pikeun ngahasilkeun angka dina kaulinan, kami nganggo Oracle - éksternal, sistem non-blockchain. Server ngalakukeun tanda tangan RSA tina id kaulinan. Kontrak pinter pariksa validitas tanda tangan sareng nangtukeun juara. Lamun server teu ngirim nanaon, pamaké otomatis meunang.
Ieu métode generasi jujur, sabab manipulasi téhnisna teu mungkin. Sadaya kaulinan Tradisys dianggo dumasar kana algoritma anu dijelaskeun. Ieu kumaha kaulinan blockchain dianggo. Sadayana transparan sareng tiasa diverifikasi. Henteu aya analog tina sistem sapertos kitu dina blockchain anu sanés. Ieu acak adil.
sumber: www.habr.com