Ada masalah yang perlu kami tangani saat mengembangkan game kami. Sangat rumit untuk menghasilkan nomor acak dalam jaringan terdistribusi. Hampir semua blockchain sudah menghadapi masalah ini. Memang, dalam jaringan di mana tidak ada kepercayaan di antara siapa pun, penciptaan nomor acak memecahkan berbagai masalah.
Dalam artikel ini, kami menjelaskan bagaimana kami memecahkan masalah ini untuk permainan kami. Yang pertama adalah
Waves Xmas Tree .

Awalnya, kami berencana untuk menghasilkan angka menggunakan informasi dari blockchain. Namun, pada penyelidikan lebih lanjut, menjadi jelas bahwa proses yang digunakan untuk membuat nomor dengan cara ini dapat dimanipulasi. Kami harus membuang solusi ini.
Kami menemukan solusi, menggunakan skema 'commit-express'. Server mengusulkan angka dari 1 hingga 5, menambahkan 'garam' ke dalamnya dan
memotong hasilnya menggunakan
fungsi Keccak . Server melakukan pra-debug kontrak pintar dengan nomor yang sudah disimpan. Hasilnya adalah bahwa permainan dikurangi secara efektif hingga pengguna menebak nomor yang disembunyikan oleh hash.
Pemain memasang taruhan mereka dan server mengirim nomor tersembunyi dan 'garam' ke kontrak pintar. Dengan kata lain, kartu-kartu itu terungkap. Setelah itu, server memverifikasi nomor dan memutuskan apakah pengguna menang atau kalah.
Jika server tidak mengirim nomor dan 'garam' untuk verifikasi, maka pengguna menang. Dalam hal ini, perlu untuk menggunakan kontrak pintar terlebih dahulu dan mengatur potensi kemenangan untuk setiap pertandingan. Ini tidak nyaman, mahal dan memakan waktu. Namun, pada saat itu, tidak ada solusi aman lainnya.
Tak lama kemudian, tim Tradisys mengusulkan menambahkan fungsi
rsaVerify () ke protokol Waves. Ini memeriksa validitas tanda tangan RSA berdasarkan kunci publik dan pribadi. Sebagai hasil dari proposal kami, fungsi ditambahkan.
Kami membuat tiga game baru:
Dice Roller ,
Coin Flip dan
Ride On Waves . Di masing-masing dari mereka, teknologi nomor acak baru diimplementasikan. Mari kita lihat lebih dekat cara kerjanya.

Mari kita lihat generasi nomor acak terlebih dahulu. Anda dapat menemukan kontrak pintar di
sini .
Buka
tab Skrip dan pilih
Dompilasi . Anda akan melihat kode kontrak pintar (atau skrip).

Kode kontrak pintar terdiri dari daftar fungsi. Yang @Callable dapat dijalankan melalui
transaksi Doa . Kami tertarik pada dua di antaranya:
bertaruh dan
menarik :
- func bet (pemain Pilih)
- func withdraw (gameId, rsaSign)
1. Pengguna memilih rentang dan ukuran taruhan.

2. Klien mengatur fungsi taruhan. Untuk gambar di atas adalah
taruhan ("50")3. Klien mengirimkan transaksi Invokasi ke alamat kontrak pintar (broadcast InvocationTx). Transaksi sebagai parameter Panggilan berisi fungsi taruhan. Ini berarti bahwa transaksi Invokasi memulai pelaksanaan fungsi taruhan pada kontrak pintar (pilihan: String).

4. Mari kita lihat fungsi taruhan:
@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 ini merekam game baru dalam status kontrak pintar:
- Id game baru yang unik (id game)
- Status permainan = SUBMITTED
- Pilihan pemain (kisarannya 50)
- Kunci publik
- Potensi hadiah (tergantung pada taruhan pemain)

Inilah tampilan database nilai kunci pada blockchain:
{ "type": "string", "value": "03WON_0283_448t8Jn9P3717UnXFEVD5VWjfeGE5gBNeWg58H2aJeQEgJ_06574069_09116020000_0229", "key": "2GKTX6NLTgUrE4iy9HtpSSHpZ3G8W4cMfdjyvvnc21dx" }
'Kunci' adalah
id game untuk game baru. Data yang tersisa terkandung dalam bidang 'nilai'. Entri-entri ini disimpan di tab
Data pada kontrak pintar:


5. Server menemukan transaksi terkirim (game baru) melalui blockchain API. Id game sudah direkam di blockchain, jadi tidak mungkin untuk mengubah atau menghapusnya.
6. Server membentuk fungsi penarikan (gameId, rsaSign) seperti:
menarik ( «FwsuaaShC6DMWdSWQ5osGWtYkVbTEZrsnxqDbVx5oUpq», «base64: Gy69dKdmXUEsAmUrpoWxDLTQOGj5 / qO8COA + QjyPVYTAjxXYvEESJbSiCSBRRCOAliqCWwaS161nWqoTL / TltiIvw3nKyd4RJIBNSIgEWGM1tEtNwwnRwSVHs7ToNfZ2Dvk / GgPUqLFDSjnRQpTHdHUPj9mQ8erWw0r6cJXrzfcagKg3yY / 0wJ6AyIrflR35mUCK4cO7KumdvC9Mx0hr / ojlHhN732nuG8ps4CUlRw3CkNjNIajBUlyKQwpBKmmiy3yJa / QM5PLxqdppmfFS9y0sxgSlfLOgZ51xRDYuS8NViOA7c1JssH48ZtDbBT5yqzRJXs3RnmZcMDr / q0x6Bg ==»)
7. Server mengirimkan transaksi Invokasi ke kontrak pintar (broadcast InvocationTx). Transaksi berisi panggilan ke fungsi penarikan yang dibuat (gameId, rsaSign):

Fungsi ini berisi
id game dan tanda tangan RSA dari id unik. Hasil tanda tangan tidak dapat diubah.
Apa artinya ini?
Kami mengambil nilai yang sama (id game) dan menerapkan metode tanda tangan RSA untuk itu. Ini adalah cara kerja algoritma RSA. Tidak mungkin untuk memanipulasi angka akhir karena
id game dan hasil dari algoritma RSA tidak diketahui. Tidak ada gunanya mencoba menebak angka.
8. Blockchain menerima transaksi yang menjalankan fungsi penarikan (gameId, rsaSign).
9. Ada panggilan untuk fungsi GenerateRandIn di dalam fungsi withdraw (gameId, rsaSign). Ini adalah pembangkit 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 adalah angka acak
Pertama, string yang merupakan hasil dari tanda tangan RSA diambil. Kemudian, di-hash melalui SHA-256 (
sha256 (rsaSign) ).
Kami tidak dapat memprediksi hasil tanda tangan dan hashing selanjutnya. Jadi, tidak mungkin untuk mempengaruhi generasinya. Untuk mendapatkan nomor dalam rentang tertentu (mis. Dari 1 hingga 100), fungsi konversi keInt dan% 100 (
mod analog) diterapkan.
Pada awal artikel, kami menyebutkan fungsi
rsaVerify () yang memungkinkan pengecekan validitas tanda tangan RSA oleh kunci pribadi terhadap yang publik. Ini adalah bagian dari GenerateRandInt (gameId, rsaSign):
rsaVerify (SHA256, toBytes (gameId), rsaSign, RSAPUBLIC)
Untuk mulai dengan, kunci publik RSAPUBLIC dan string rsaSign diambil. Tanda tangan diperiksa untuk validitasnya. Jika cek berhasil, nomor yang dihasilkan. Jika tidak, sistem menganggap bahwa tanda tangan tidak valid (tanda tangan RSA tidak valid).
Server harus menandatangani id game menggunakan kunci pribadi dan mengirim tanda tangan RSA yang valid dalam 2.880 blok. Opsi ini dikelola saat kontrak pintar digunakan. Jika tidak ada yang terjadi dalam waktu yang ditentukan, pengguna menang. Dalam hal ini, hadiah harus dikirim oleh pengguna secara mandiri. Ternyata menipu itu tidak menguntungkan bagi server karena ini menyebabkan kerugian. Ada contoh di bawah ini.

Pengguna memainkan
Dice Roller . Dia memilih 2 dari 6 wajah kubus, dengan taruhan 14 GELOMBANG. Jika server tidak mengirim tanda tangan RSA yang valid ke kontrak pintar dalam waktu yang ditentukan (2.880 blok), pengguna akan menerima 34,44 GELOMBANG.
Untuk generasi nomor, kami menggunakan oracle, sistem eksternal daripada blockchain. Server mengimplementasikan tanda tangan RSA untuk id game. Kontrak pintar memeriksa validitas tanda tangan dan menentukan pemenang. Jika server tidak mengirim apa pun, maka pengguna akan menang secara otomatis.
Metode ini memastikan bahwa manipulasi secara teknis tidak mungkin. Semua game Tradisys didasarkan pada algoritma yang dijelaskan di atas - memastikan game kami adil dan transparan. Semuanya bisa diaudit secara publik untuk memastikan kejujuran.