Ada masalah - sulit untuk menghasilkan nomor acak di jaringan yang didesentralisasi. Hampir semua blockchain telah mengalami ini. Memang, dalam jaringan di mana tidak ada kepercayaan di antara pengguna, penciptaan nomor acak yang tak terbantahkan memecahkan banyak masalah.
Artikel ini menceritakan cara mengatasi masalah menggunakan game sebagai contoh. Yang pertama adalah
Pohon Natal Gelombang . Untuk pengembangan, kami membutuhkan generator angka acak.

Awalnya, kami berencana untuk menghasilkan nomor berdasarkan informasi dari blockchain. Namun, kemudian menjadi jelas: jumlahnya bisa dicurangi, yang berarti solusinya tidak cocok.
Kami menemukan solusi: gunakan skema pengungkapan komitmen. Server "menebak" angka dari 1 hingga 5, menambahkan "garam" ke dalamnya, dan kemudian
mengacak hasilnya menggunakan
fungsi Keccak . Server pra-menyebarkan kontrak pintar dengan nomor yang sudah disimpan. Ternyata permainan dikurangi menjadi fakta bahwa pengguna menebak nomor yang disembunyikan oleh hash.
Pemain membuat taruhan, dan server mengirim nomor yang diminta dan "garam" ke kontrak pintar. Dalam bahasa yang sederhana, ia mengungkapkan kartunya. Setelah itu, server memverifikasi nomor dan memutuskan apakah pengguna menang atau kalah.
Jika server tidak mengirim nomor atau "garam" untuk verifikasi, pengguna menang. Dalam hal ini, untuk setiap pertandingan itu perlu untuk menggunakan kontrak pintar di muka dan meletakkan potensi kemenangan di dalamnya. Ternyata tidak nyaman, panjang dan mahal. Saat itu, tidak ada solusi aman lainnya.
Baru-baru ini, tim Tradisys telah mengusulkan penambahan fungsi
rsaVerify () ke protokol Waves. Ini memverifikasi validitas tanda tangan RSA berdasarkan kunci publik dan pribadi. Akibatnya, fungsi itu ditambahkan.
Kami mengembangkan tiga game:
Dice Roller ,
Coin Flip dan
Ride On Waves . Setiap menerapkan teknologi angka acak. Mari kita lihat cara kerjanya.

Pertimbangkan pembuatan bilangan acak menggunakan Ride on Waves sebagai contoh. Kontrak pintar dapat ditemukan di
sini .
Buka tab
Skrip dan pilih
Dompilasi . Lihat kode kontrak pintar (skrip alias).

Kode kontrak pintar berisi serangkaian fungsi. Yang ditandai sebagai @Callable dapat dipicu menggunakan
transaksi Invokasi. Kami tertarik pada dua fungsi:
bertaruh dan
menarik :
- func bet (pemain Pilih)
- func withdraw (gameId, rsaSign)
1. Pengguna memilih panjang segmen dan ukuran taruhan.

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

4. Pertimbangkan 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 menulis game baru ke status kontrak pintar. Yaitu:
- Pengidentifikasi unik untuk game baru (id game)
- Status permainan = SUBMITTED
- Pilihan pemain (panjang garis 50)
- Kunci publik
- Kemenangan potensial (tergantung pada taruhan pemain)

Ini adalah bagaimana catatan data di blockchain terlihat seperti (nilai kunci):
{ "type": "string", "value": "03WON_0283_448t8Jn9P3717UnXFEVD5VWjfeGE5gBNeWg58H2aJeQEgJ_06574069_09116020000_0229", "key": "2GKTX6NLTgUrE4iy9HtpSSHpZ3G8W4cMfdjyvvnc21dx" }
"Kunci" (kunci) -
id game dari game baru. Data yang tersisa terkandung dalam garis "nilai" bidang (nilai). Entri-entri ini disimpan di tab
Data pada kontrak pintar:


5. Server “melihat” kontrak pintar dan menemukan transaksi yang dikirim (permainan baru) menggunakan blockchain Api. Id game dari game baru sudah direkam di blockchain, yang berarti tidak mungkin lagi untuk mengubah atau mempengaruhinya
6. Server membentuk fungsi penarikan (gameId, rsaSign). Sebagai contoh, ini:
withdraw ("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 dari game baru dan hasil tanda tangan RSA dari pengidentifikasi unik dengan kunci pribadi. Hasil tanda tangan tidak berubah.
Apa artinya ini?Kami mengambil nilai yang sama (id game) dan menerapkan metode tanda tangan RSA untuk itu. Kami akan selalu mendapatkan hasil yang sama. Ini adalah cara kerja algoritma RSA. Anda tidak dapat memanipulasi angka terakhir, karena id game dan hasil penggunaan RSA tidak diketahui. Mencocokkan angka juga tidak ada gunanya.
8. Blockchain menerima transaksi. Ini menjalankan fungsi penarikan (gameId, rsaSign)
9. Di dalam fungsi withdraw,
fungsi GenerateRandInt (gameId, rsaSign) diekspor. 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 - dan ada nomor acak.
Pertama, sebuah string diambil, yang merupakan hasil dari tanda tangan RSA
id game dengan kunci pribadi (
rsaSign ). Kemudian hash menggunakan SHA-256 (
sha256 (rsaSign) ).
Kami tidak dapat memprediksi hasil tanda tangan dan hashing selanjutnya. Oleh karena itu, tidak mungkin untuk mempengaruhi pembangkitan bilangan acak. Untuk mendapatkan nomor dalam rentang tertentu (misalnya, dari 1 hingga 100), fungsi konversi toInt dan% 100 digunakan (analog ke
mod ).
Di awal artikel, kami menyebutkan fungsi
rsaVerify () , yang memungkinkan Anda memverifikasi validitas tanda tangan RSA dengan kunci pribadi dengan kunci publik. Inilah bagian GenerateRandInt (gameId, rsaSign):
rsaVerify (SHA256, toBytes(gameId), rsaSign, RSAPUBLIC)
Kunci publik RSAPUBLIC dan string rsaSign diteruskan ke input. Tanda tangan diperiksa untuk validitasnya. Sejumlah dihasilkan jika cek berhasil. Jika tidak, sistem menganggap bahwa tanda tangan tidak valid (tanda tangan RSA tidak valid).
Server harus menandatangani id game dengan kunci pribadi dan mengirim tanda tangan Rsa yang valid dalam 2880 blok. Parameter ini dikonfigurasi saat menggunakan kontrak pintar. Jika tidak ada yang terjadi selama waktu yang ditentukan, pengguna menang. Dalam hal ini, hadiah harus dikirim ke alamat Anda sendiri. Ternyata server "tidak menguntungkan untuk menipu", karena ini menyebabkan kerugian. Di bawah ini adalah contohnya.

Pengguna memainkan
Dice Roller . Saya memilih 2 dari 6 wajah kubus, taruhannya adalah 14 GELOMBANG. Jika server tidak mengirim tanda tangan RSA yang valid pada kontrak pintar dalam waktu yang ditentukan (2880 blok), pengguna akan mengambil 34,44 WAVES.
Untuk menghasilkan angka dalam gim, kami menggunakan oracle - sistem eksternal yang tidak menghalangi. Server mengimplementasikan id game tanda tangan RSA. Kontrak pintar memeriksa validitas tanda tangan dan menentukan pemenang. Jika server tidak mengirim apa pun, maka pengguna otomatis menang.
Metode yang dijelaskan memastikan bahwa manipulasi secara teknis tidak mungkin. Semua game Tradisys menggunakan algoritme, sehingga jujur dan transparan. Semuanya cocok untuk pengawasan publik. Ini memastikan kejujuran.