RSA rawak pada blockchain

Terdapat masalah - sukar untuk menjana nombor rawak dalam rangkaian terdesentralisasi. Hampir semua rantaian blok telah pun mengalami perkara ini. Sesungguhnya, dalam rangkaian yang tidak ada kepercayaan antara pengguna, mencipta nombor rawak yang tidak dapat dinafikan menyelesaikan banyak masalah.

Dalam artikel ini kami memberitahu anda bagaimana kami berjaya menyelesaikan masalah menggunakan permainan sebagai contoh. Yang pertama daripada mereka ialah Pokok Xmas Gelombang. Untuk pembangunan, kami memerlukan penjana nombor rawak.

RSA rawak pada blockchain

Pada mulanya, kami merancang untuk menjana nombor berdasarkan maklumat daripada blockchain. Walau bagaimanapun, ia menjadi jelas: nombor itu boleh dimanipulasi, yang bermaksud penyelesaiannya tidak sesuai.

Kami menghasilkan penyelesaian: gunakan skema commit-expand. Pelayan meneka nombor dari 1 hingga 5, menambah garam padanya, dan kemudian mencincang hasilnya menggunakan Fungsi Keccak. Pelayan menggunakan kontrak pintar dengan nombor yang telah disimpan terlebih dahulu. Ternyata permainan ini bermuara kepada pengguna meneka nombor yang disembunyikan oleh cincang.

Pemain meletakkan taruhan, dan pelayan menghantar nombor tersembunyi dan "garam" kepada kontrak pintar. Secara ringkas, dia mendedahkan kad itu. Selepas itu, pelayan menyemak nombor dan memutuskan sama ada pengguna menang atau kalah.

Jika pelayan tidak menghantar nombor atau "garam" untuk pengesahan, pengguna menang. Dalam kes ini, untuk setiap permainan adalah perlu untuk menggunakan kontrak pintar terlebih dahulu dan memasukkan potensi kemenangan di dalamnya. Ia ternyata menyusahkan, memakan masa dan mahal. Pada masa itu tidak ada penyelesaian lain yang selamat.

Baru-baru ini, pasukan Tradisys mencadangkan penambahan fungsi pada protokol Waves rsaVerify(). Ia menyemak kesahihan tandatangan RSA berdasarkan kunci awam dan peribadi. Akibatnya, ciri itu telah ditambah.

Kami telah membangunkan tiga permainan: Kata Roller, Pembalik Syiling ΠΈ Menunggang Ombak. Setiap satu melaksanakan teknologi nombor rawak. Mari kita fikirkan bagaimana ia berfungsi.

RSA rawak pada blockchain

Mari lihat menjana nombor rawak menggunakan Ride on Waves sebagai contoh. Kontrak pintar boleh didapati di sini.

Klik tab skrip dan pilih Disusun semula. Anda akan melihat kod kontrak pintar (aka skrip).

RSA rawak pada blockchain

Kod kontrak pintar mengandungi satu set fungsi. Mereka yang ditandakan sebagai @Callable boleh dilancarkan menggunakan Urus niaga seruan. Kami berminat dengan dua fungsi: bertaruh ΠΈ menarik diri:

  • pertaruhan func (playerChoice)
  • func withdraw(gameId,rsaSign)

1. Pengguna memilih panjang segmen dan saiz pertaruhan.

RSA rawak pada blockchain

2. Pelanggan mencipta fungsi pertaruhan. Untuk imej di atas ia akan menjadi pertaruhan("50").

3. Pelanggan menghantar transaksi Invocation ke alamat kontrak pintar (broadcast InvocationTx). Urus niaga mengandungi fungsi pertaruhan sebagai parameter panggilan. Ini bermakna transaksi Invocation mencetuskan pelaksanaan fungsi pertaruhan (pilihan: Rentetan) pada kontrak pintar.

RSA rawak pada blockchain

4. Pertimbangkan fungsi pertaruhan:

@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 permainan baharu kepada keadaan kontrak pintar. Iaitu:

  • Pengecam unik untuk permainan baharu (id permainan)
  • Keadaan permainan = DISERAHKAN
  • Pilihan pemain (panjang segmen 50)
  • Kunci awam
  • Potensi kemenangan (bergantung pada pertaruhan pemain)

RSA rawak pada blockchain

Beginilah rupa rekod data dalam blockchain (nilai-kunci):

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

"Kunci" (kunci) - id permainan permainan baru. Data selebihnya terkandung dalam baris medan "nilai". Entri ini disimpan dalam tab Tarikh kontrak pintar:

RSA rawak pada blockchain

RSA rawak pada blockchain

5. Pelayan "melihat" kontrak pintar dan mencari transaksi yang dihantar (permainan baharu) menggunakan blockchain Api. Id Permainan bagi permainan baharu itu sudah pun direkodkan dalam rantaian blok, yang bermaksud ia tidak lagi boleh diubah atau dipengaruhi

6. Pelayan menjana fungsi penarikan (gameId, rsaSign). Sebagai contoh, seperti ini:

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

7. Pelayan menghantar transaksi Invocation ke kontrak pintar (broadcast InvocationTx). Urus niaga mengandungi panggilan ke fungsi penarikan yang dibentuk (gameId, rsaSign):

RSA rawak pada blockchain

Fungsi mengandungi id permainan permainan baharu dan hasil tandatangan RSA bagi pengecam unik dengan kunci persendirian. Hasil tandatangan tidak berubah.

Apa maknanya?

Kami mengambil nilai yang sama (id permainan) dan menggunakan kaedah tandatangan RSA padanya. Kami akan sentiasa mendapat keputusan yang sama. Inilah cara algoritma RSA berfungsi. Nombor akhir tidak boleh dimanipulasi, kerana id permainan dan keputusan menggunakan RSA tidak diketahui. Memilih nombor juga tidak berguna.

8. Blockchain menerima transaksi. Ia menjalankan fungsi withdraw (gameId, rsaSign)

9. Di dalam fungsi pengeluaran, pengeluaran berlaku Fungsi GenerateRandInt (gameId, rsaSign). Ini adalah penjana nombor rawak

# @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 terdapat nombor rawak.

Pertama, rentetan diambil, yang merupakan hasil tandatangan RSA id permainan kunci peribadi (rsaSign). Kemudian cincang dengan SHA-256 (sha256(rsaSign)).

Kami tidak boleh meramalkan hasil tandatangan dan pencincangan seterusnya. Oleh itu, adalah mustahil untuk mempengaruhi penjanaan nombor rawak. Untuk mendapatkan nombor dalam julat tertentu (contohnya, dari 1 hingga 100), gunakan fungsi penukaran toInt dan %100 (serupa dengan mod).

Pada permulaan artikel kami menyebut fungsi rsaVerify(), yang membolehkan anda menyemak kesahihan tandatangan RSA menggunakan kunci persendirian terhadap kunci awam. Berikut ialah bahagian GenerateRandInt(gameId,rsaSign):

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

Kunci awam RSAPUBLIC dan rentetan rsaSign dihantar ke input. Tandatangan disemak untuk kesahihannya. Nombor dijana jika semakan berjaya. Jika tidak, sistem menganggap bahawa tandatangan itu tidak sah (Tandatangan RSA tidak sah).

Pelayan mesti menandatangani id permainan dengan kunci peribadi dan menghantar tandatangan Rsa yang sah dalam 2880 blok. Parameter dikonfigurasikan apabila menggunakan kontrak pintar. Jika tiada apa-apa berlaku dalam masa yang ditetapkan, pengguna menang. Dalam kes ini, hadiah mesti dihantar ke alamat anda sendiri. Ternyata "tidak menguntungkan pelayan untuk menipu", kerana ini membawa kepada kerugian. Di bawah adalah contoh.

RSA rawak pada blockchain

Pengguna sedang bermain Kata Roller. Saya memilih 2 daripada 6 sisi kubus, taruhannya ialah 14 GELOMBANG. Jika pelayan tidak menghantar tandatangan RSA yang sah kepada kontrak pintar dalam masa yang ditetapkan (2880 blok), pengguna akan mengambil 34.44 GELOMBANG.

Untuk menjana nombor dalam permainan, kami menggunakan oracle - sistem luaran bukan rantaian sekat. Pelayan melakukan tandatangan RSA bagi id permainan. Kontrak pintar menyemak kesahihan tandatangan dan menentukan pemenang. Jika pelayan tidak menghantar apa-apa, maka pengguna secara automatik menang.

Ini adalah kaedah penjanaan yang jujur, kerana manipulasi secara teknikal adalah mustahil. Semua permainan Tradisys berfungsi berdasarkan algoritma yang diterangkan. Beginilah cara permainan blockchain berfungsi. Semuanya telus dan boleh disahkan. Tiada analog sistem sedemikian dalam mana-mana blockchain lain. Ini adalah rawak yang adil.

Sumber: www.habr.com

Tambah komen