RSA ngẫu nhiên trên blockchain

Có một vấn đề - rất khó để tạo một số ngẫu nhiên trong mạng phi tập trung. Hầu như tất cả các blockchain đều đã gặp phải điều này. Thật vậy, trong các mạng không có sự tin tưởng giữa người dùng, việc tạo ra một số ngẫu nhiên không thể phủ nhận sẽ giải quyết được nhiều vấn đề.

Trong bài viết này, chúng tôi sẽ cho bạn biết cách chúng tôi giải quyết vấn đề bằng cách sử dụng trò chơi làm ví dụ. Người đầu tiên trong số họ là Cây Giáng Sinh Sóng. Để phát triển, chúng tôi cần một trình tạo số ngẫu nhiên.

RSA ngẫu nhiên trên blockchain

Ban đầu, chúng tôi dự định tạo một số dựa trên thông tin từ blockchain. Tuy nhiên, sau đó mọi chuyện trở nên rõ ràng: con số có thể bị thao túng, nghĩa là giải pháp không phù hợp.

Chúng tôi đã nghĩ ra một giải pháp thay thế: sử dụng lược đồ mở rộng cam kết. Máy chủ đoán một số từ 1 đến 5, thêm muối vào đó rồi băm kết quả bằng cách sử dụng Chức năng Keccak. Máy chủ đã triển khai hợp đồng thông minh với số lượng đã lưu trước. Hóa ra trò chơi tập trung vào việc người dùng đoán số được hàm băm ẩn.

Người chơi đặt cược và máy chủ đã gửi số ẩn và “muối” đến hợp đồng thông minh. Nói một cách đơn giản, anh ta đã tiết lộ những lá bài. Sau đó, máy chủ kiểm tra các con số và quyết định người dùng thắng hay thua.

Nếu máy chủ không gửi số hoặc “muối” để xác minh, người dùng sẽ thắng. Trong trường hợp này, đối với mỗi trò chơi, cần phải triển khai trước một hợp đồng thông minh và bao gồm tiền thắng tiềm năng trong đó. Nó hóa ra là bất tiện, tốn thời gian và tốn kém. Lúc đó không có giải pháp an toàn nào khác.

Gần đây, nhóm Tradisys đã đề xuất thêm một chức năng vào giao thức Waves rsaVerify(). Nó kiểm tra tính hợp lệ của chữ ký RSA dựa trên khóa chung và khóa riêng. Kết quả là tính năng này đã được thêm vào.

Chúng tôi đã phát triển ba trò chơi: Nói con lăn, Coin Flip и Cưỡi Trên Sóng. Mỗi người thực hiện công nghệ số ngẫu nhiên. Hãy tìm hiểu cách nó hoạt động.

RSA ngẫu nhiên trên blockchain

Hãy xem việc tạo một số ngẫu nhiên bằng cách sử dụng Ride on Waves làm ví dụ. Hợp đồng thông minh có thể được tìm thấy đây.

Đi tới tab Script và chọn Dịch ngược. Bạn sẽ thấy mã hợp đồng thông minh (còn gọi là tập lệnh).

RSA ngẫu nhiên trên blockchain

Mã hợp đồng thông minh chứa một tập hợp các chức năng. Những thứ được đánh dấu là @Callable có thể được khởi chạy bằng cách sử dụng Giao dịch gọi. Chúng tôi quan tâm đến hai chức năng: đặt cược и Thu hồi:

  • đặt cược func (playerChoice)
  • rút tiền func(gameId,rsaSign)

1. Người dùng chọn độ dài của đoạn và kích thước đặt cược.

RSA ngẫu nhiên trên blockchain

2. Khách hàng tạo chức năng đặt cược. Đối với hình ảnh trên nó sẽ là đặt cược("50").

3. Khách hàng gửi giao dịch Invocation đến địa chỉ hợp đồng thông minh (phát InvocationTx). Giao dịch chứa chức năng đặt cược làm tham số cuộc gọi. Điều này có nghĩa là giao dịch Invocation kích hoạt việc thực thi chức năng đặt cược (lựa chọn: Chuỗi) trên hợp đồng thông minh.

RSA ngẫu nhiên trên blockchain

4. Xét hàm đặt cược:

@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)))
                    }
    }

Hàm ghi một trò chơi mới vào trạng thái của hợp đồng thông minh. Cụ thể là:

  • Mã định danh duy nhất cho trò chơi mới (mã số game)
  • Trạng thái trò chơi = ĐĂNG KÝ
  • Lựa chọn của người chơi (độ dài đoạn 50)
  • Khóa công khai
  • Tiền thắng tiềm năng (tùy thuộc vào đặt cược của người chơi)

RSA ngẫu nhiên trên blockchain

Đây là bản ghi dữ liệu trong blockchain trông như thế nào (khóa-giá trị):

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

"Chìa khóa" (chìa khóa) – mã số game trò chơi mới. Dữ liệu còn lại được chứa trong dòng của trường “giá trị”. Các mục này được lưu trữ trong tab Ngày hợp đồng thông minh:

RSA ngẫu nhiên trên blockchain

RSA ngẫu nhiên trên blockchain

5. Máy chủ “xem xét” hợp đồng thông minh và tìm thấy giao dịch đã gửi (trò chơi mới) bằng cách sử dụng Api blockchain. Id trò chơi của trò chơi mới đã được ghi lại trong blockchain, điều đó có nghĩa là nó không thể bị thay đổi hoặc ảnh hưởng nữa

6. Máy chủ tạo chức năng rút tiền (gameId, rsaSign). Ví dụ như thế này:

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

7. Máy chủ gửi giao dịch Invocation đến hợp đồng thông minh (phát InvocationTx). Giao dịch chứa lệnh gọi đến chức năng rút tiền đã hình thành (gameId, rsaSign):

RSA ngẫu nhiên trên blockchain

Hàm chứa mã số game trò chơi mới và kết quả của việc ký RSA vào một mã định danh duy nhất bằng khóa riêng. Kết quả chữ ký không thay đổi.

Điều này có nghĩa là gì?

Chúng tôi lấy cùng một giá trị (id trò chơi) và áp dụng phương pháp chữ ký RSA cho nó. Chúng ta sẽ luôn nhận được kết quả tương tự. Đây là cách thuật toán RSA hoạt động. Không thể thao tác số cuối cùng vì không biết id trò chơi và kết quả áp dụng RSA. Chọn một con số cũng vô nghĩa.

8. Blockchain chấp nhận giao dịch. Nó chạy chức năng rút tiền (gameId, rsaSign)

9. Bên trong chức năng rút tiền, việc rút tiền diễn ra Hàm TạoRandInt (gameId, rsaSign). Đây là một trình tạo số ngẫu nhiên

# @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 - và có một số ngẫu nhiên.

Đầu tiên, chuỗi được lấy, là kết quả của chữ ký RSA mã số game khóa riêng (rsaSign). Sau đó được băm bằng SHA-256 (sha256(rsaSign)).

Chúng ta không thể dự đoán kết quả của chữ ký và phép băm tiếp theo. Vì vậy, không thể ảnh hưởng đến việc tạo ra một số ngẫu nhiên. Để lấy một số trong một phạm vi nhất định (ví dụ: từ 1 đến 100), hãy sử dụng hàm chuyển đổi toInt và %100 (tương tự như mod).

Ở đầu bài viết chúng tôi đã đề cập đến chức năng rsaVerify(), cho phép bạn kiểm tra tính hợp lệ của chữ ký RSA bằng khóa riêng so với khóa chung. Đây là phần GeneratorRandInt(gameId,rsaSign):

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

Khóa công khai RSAPUBLIC và chuỗi rsaSign được chuyển vào đầu vào. Chữ ký được kiểm tra tính hợp lệ. Số được tạo nếu kiểm tra thành công. Ngược lại, hệ thống coi chữ ký không hợp lệ (Chữ ký RSA không hợp lệ).

Máy chủ phải ký id trò chơi bằng khóa riêng và gửi chữ ký Rsa hợp lệ trong vòng 2880 khối. Tham số được cấu hình khi triển khai hợp đồng thông minh. Nếu không có gì xảy ra trong thời gian quy định, người dùng sẽ thắng. Trong trường hợp này, giải thưởng phải được gửi đến địa chỉ của bạn. Hóa ra việc máy chủ gian lận “không có lãi”, vì điều này dẫn đến thua lỗ. Dưới đây là một ví dụ.

RSA ngẫu nhiên trên blockchain

Người dùng đang chơi Nói con lăn. Tôi đã chọn 2 trong 6 mặt của khối lập phương, đặt cược là 14 WAVES. Nếu máy chủ không gửi chữ ký RSA hợp lệ đến hợp đồng thông minh trong thời gian quy định (2880 khối), người dùng sẽ mất 34.44 WAVES.

Để tạo số trong trò chơi, chúng tôi sử dụng oracle - một hệ thống bên ngoài, không phải blockchain. Máy chủ thực hiện chữ ký RSA của id trò chơi. Hợp đồng thông minh kiểm tra tính hợp lệ của chữ ký và xác định người chiến thắng. Nếu máy chủ không gửi bất cứ thứ gì thì người dùng sẽ tự động thắng.

Đây là một phương pháp tạo trung thực vì về mặt kỹ thuật, việc thao túng là không thể. Tất cả các trò chơi Tradisys đều hoạt động dựa trên thuật toán được mô tả. Đây là cách trò chơi blockchain hoạt động. Mọi thứ đều minh bạch và có thể kiểm chứng. Không có sự tương tự của hệ thống như vậy trong bất kỳ blockchain nào khác. Đây là một sự ngẫu nhiên công bằng.

Nguồn: www.habr.com

Thêm một lời nhận xét