RSA สุ่มบน blockchain

มีปัญหาเกิดขึ้น - เป็นการยากที่จะสร้างตัวเลขสุ่มในเครือข่ายแบบกระจายอำนาจ บล็อกเชนเกือบทั้งหมดเคยเจอสิ่งนี้มาแล้ว แท้จริงแล้ว ในเครือข่ายที่ไม่มีความไว้วางใจระหว่างผู้ใช้ การสร้างตัวเลขสุ่มที่ปฏิเสธไม่ได้จะช่วยแก้ปัญหาได้มากมาย

ในบทความนี้ เราจะบอกคุณว่าเราจัดการแก้ไขปัญหาโดยใช้เกมเป็นตัวอย่างได้อย่างไร คนแรกคือ คลื่นคริสต์มาสต้นไม้. สำหรับการพัฒนา เราต้องการเครื่องสร้างตัวเลขสุ่ม

RSA สุ่มบน blockchain

ในตอนแรก เราวางแผนที่จะสร้างตัวเลขตามข้อมูลจากบล็อคเชน อย่างไรก็ตาม เป็นที่ชัดเจนว่าตัวเลขสามารถปรับเปลี่ยนได้ ซึ่งหมายความว่าวิธีแก้ปัญหานี้ไม่เหมาะสม

เราพบวิธีแก้ปัญหา: ใช้รูปแบบการคอมมิตและขยาย เซิร์ฟเวอร์เดาตัวเลขตั้งแต่ 1 ถึง 5 เติมเกลือลงไป จากนั้นแฮชผลลัพธ์โดยใช้ ฟังก์ชันเค็กคัก. เซิร์ฟเวอร์ปรับใช้สัญญาอัจฉริยะด้วยหมายเลขที่บันทึกไว้ล่วงหน้า ปรากฎว่าเกมนี้ขึ้นอยู่กับผู้ใช้ที่เดาตัวเลขที่ซ่อนอยู่ในแฮช

ผู้เล่นวางเดิมพัน และเซิร์ฟเวอร์ส่งหมายเลขที่ซ่อนอยู่และ “เกลือ” ไปยังสัญญาอัจฉริยะ พูดง่ายๆ ก็คือ เขาเปิดเผยไพ่ หลังจากนั้นเซิร์ฟเวอร์จะตรวจสอบหมายเลขและตัดสินใจว่าผู้ใช้ชนะหรือแพ้

หากเซิร์ฟเวอร์ไม่ได้ส่งหมายเลขหรือ “เกลือ” เพื่อตรวจสอบ ผู้ใช้จะชนะ ในกรณีนี้ ในแต่ละเกมจำเป็นต้องปรับใช้สัญญาอัจฉริยะล่วงหน้าและรวมชัยชนะที่อาจเกิดขึ้นไว้ด้วย กลับกลายเป็นว่าไม่สะดวก ใช้เวลานาน และมีราคาแพง ในเวลานั้นยังไม่มีวิธีแก้ปัญหาที่ปลอดภัยอื่นใด

เมื่อเร็วๆ นี้ทีมงาน Tradisys ได้เสนอให้เพิ่มฟังก์ชันให้กับโปรโตคอล Waves rsaVerify(). จะตรวจสอบความถูกต้องของลายเซ็น RSA ตามรหัสสาธารณะและส่วนตัว เป็นผลให้มีการเพิ่มคุณสมบัติ

เราได้พัฒนาเกมสามเกม: ลูกกลิ้งลูกเต๋า, Coin Flip и ขี่บนคลื่น. แต่ละคนใช้เทคโนโลยีตัวเลขสุ่ม เรามาดูกันว่ามันทำงานอย่างไร

RSA สุ่มบน blockchain

มาดูการสร้างตัวเลขสุ่มโดยใช้ Ride on Waves เป็นตัวอย่าง สามารถดูสัญญาอัจฉริยะได้ ที่นี่.

ไปที่แท็บ ต้นฉบับ และเลือก ถอดรหัสแล้ว. คุณจะเห็นรหัสสัญญาอัจฉริยะ (หรือที่เรียกว่าสคริปต์)

RSA สุ่มบน blockchain

รหัสสัญญาอัจฉริยะประกอบด้วยชุดของฟังก์ชัน ผู้ที่ทำเครื่องหมายว่า @Callable สามารถเปิดใช้งานได้ ธุรกรรมการร้องขอ. เรามีความสนใจในสองฟังก์ชัน: เดิมพัน и ถอนเงิน:

  • func เดิมพัน (ตัวเลือกผู้เล่น)
  • func ถอนออก (gameId, rsaSign)

1. ผู้ใช้เลือกความยาวของส่วนและขนาดการเดิมพัน

RSA สุ่มบน blockchain

2. ลูกค้าสร้างฟังก์ชันการเดิมพัน สำหรับภาพด้านบนก็จะเป็น เดิมพัน("50").

3. ลูกค้าส่งธุรกรรมการร้องขอไปยังที่อยู่สัญญาอัจฉริยะ (ออกอากาศ InvocationTx) ธุรกรรมประกอบด้วยฟังก์ชันเดิมพันเป็นพารามิเตอร์การโทร ซึ่งหมายความว่าธุรกรรมการร้องขอจะทริกเกอร์การดำเนินการของฟังก์ชันการเดิมพัน (ตัวเลือก: สตริง) ในสัญญาอัจฉริยะ

RSA สุ่มบน blockchain

4. พิจารณาฟังก์ชันการเดิมพัน:

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

ฟังก์ชั่นเขียนเกมใหม่ให้เป็นสถานะของสัญญาอัจฉริยะ กล่าวคือ:

  • ตัวระบุที่ไม่ซ้ำสำหรับเกมใหม่ (ไอดีเกม)
  • สถานะของเกม = ส่งแล้ว
  • ตัวเลือกของผู้เล่น (ความยาวส่วน 50)
  • กุญแจสาธารณะ
  • โอกาสชนะ (ขึ้นอยู่กับการเดิมพันของผู้เล่น)

RSA สุ่มบน blockchain

นี่คือลักษณะของบันทึกข้อมูลในบล็อคเชน (คีย์-ค่า):

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

"คีย์" (คีย์) – รหัสเกม เกมส์ใหม่. ข้อมูลที่เหลือจะอยู่ในบรรทัดของช่อง "ค่า" รายการเหล่านี้จะถูกเก็บไว้ในแท็บ ข้อมูล สัญญาอัจฉริยะ:

RSA สุ่มบน blockchain

RSA สุ่มบน blockchain

5. เซิร์ฟเวอร์ “ดู” ที่สัญญาอัจฉริยะและค้นหาธุรกรรมที่ส่ง (เกมใหม่) โดยใช้ blockchain Api รหัสเกมของเกมใหม่ได้รับการบันทึกไว้ในบล็อคเชนแล้ว ซึ่งหมายความว่าไม่สามารถเปลี่ยนแปลงหรือมีอิทธิพลได้อีกต่อไป

6. เซิร์ฟเวอร์สร้างฟังก์ชันการถอน (gameId, rsaSign) ตัวอย่างเช่นเช่นนี้:

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

7. เซิร์ฟเวอร์ส่งธุรกรรมการร้องขอไปยังสัญญาอัจฉริยะ (ออกอากาศ InvocationTx) ธุรกรรมมีการเรียกไปยังฟังก์ชันการถอนที่เกิดขึ้น (gameId, rsaSign):

RSA สุ่มบน blockchain

ฟังก์ชั่นประกอบด้วย รหัสเกม เกมใหม่และผลลัพธ์ของการลงนาม RSA ของตัวระบุที่ไม่ซ้ำด้วยรหัสส่วนตัว ผลลัพธ์ลายเซ็นไม่เปลี่ยนแปลง

นี้หมายความว่าอย่างไร

เราใช้ค่าเดียวกัน (รหัสเกม) และใช้วิธีการลายเซ็น RSA กับค่านั้น เราจะได้ผลลัพธ์เหมือนเดิมเสมอ นี่คือวิธีการทำงานของอัลกอริทึม RSA ไม่สามารถจัดการหมายเลขสุดท้ายได้ เนื่องจากไม่ทราบรหัสเกมและผลลัพธ์ของการใช้ RSA การเลือกหมายเลขก็ไม่มีประโยชน์เช่นกัน

8. Blockchain ยอมรับการทำธุรกรรม มันรันฟังก์ชั่นการถอน (gameId, rsaSign)

9. ภายในฟังก์ชันการถอน การถอนจะเกิดขึ้น สร้างฟังก์ชัน RandInt (รหัสเกม, rsaSign) นี่คือเครื่องกำเนิดตัวเลขสุ่ม

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

ทั้งหมด - และมีตัวเลขสุ่ม

ขั้นแรก สตริงจะถูกนำไปใช้ ซึ่งเป็นผลลัพธ์ของลายเซ็น RSA รหัสเกม คีย์ส่วนตัว (rsaSign). จากนั้นแฮชด้วย SHA-256 (sha256(rsaSign)).

เราไม่สามารถคาดเดาผลลัพธ์ของลายเซ็นและการแฮชที่ตามมาได้ ดังนั้นจึงเป็นไปไม่ได้ที่จะมีอิทธิพลต่อการสร้างตัวเลขสุ่ม หากต้องการรับตัวเลขในช่วงที่กำหนด (เช่น ตั้งแต่ 1 ถึง 100) ให้ใช้ฟังก์ชันการแปลง toInt และ %100 (คล้ายกับ mod).

ในตอนต้นของบทความเราได้กล่าวถึงฟังก์ชันนี้แล้ว rsaVerify()ซึ่งช่วยให้คุณสามารถตรวจสอบความถูกต้องของลายเซ็น RSA ด้วยคีย์ส่วนตัวกับลายเซ็นสาธารณะได้ นี่คือส่วน GenerateRandInt(gameId,rsaSign):

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

คีย์สาธารณะ RSAPUBLIC และสตริง rsaSign ถูกส่งผ่านไปยังอินพุต ลายเซ็นจะถูกตรวจสอบความถูกต้อง หมายเลขจะถูกสร้างขึ้นหากการตรวจสอบสำเร็จ มิฉะนั้น ระบบจะถือว่าลายเซ็นไม่ถูกต้อง (ลายเซ็น RSA ไม่ถูกต้อง)

เซิร์ฟเวอร์จะต้องลงนามรหัสเกมด้วยรหัสส่วนตัวและส่งลายเซ็น Rsa ที่ถูกต้องภายใน 2880 บล็อก พารามิเตอร์ได้รับการกำหนดค่าเมื่อปรับใช้สัญญาอัจฉริยะ หากไม่มีอะไรเกิดขึ้นภายในเวลาที่กำหนด ผู้ใช้จะชนะ ในกรณีนี้จะต้องส่งรางวัลไปยังที่อยู่ของคุณด้วยตัวเอง ปรากฎว่า "เซิร์ฟเวอร์โกงไม่ได้ผลกำไร" เพราะสิ่งนี้นำไปสู่การสูญเสีย ด้านล่างนี้เป็นตัวอย่าง

RSA สุ่มบน blockchain

ผู้ใช้กำลังเล่น ลูกกลิ้งลูกเต๋า. ฉันเลือก 2 ใน 6 ด้านของลูกบาศก์ เดิมพันคือ 14 WAVES หากเซิร์ฟเวอร์ไม่ส่งลายเซ็น RSA ที่ถูกต้องไปยังสัญญาอัจฉริยะภายในเวลาที่กำหนด (2880 บล็อก) ผู้ใช้จะใช้ 34.44 WAVES

ในการสร้างตัวเลขในเกม เราใช้ออราเคิล ซึ่งเป็นระบบภายนอกที่ไม่ใช่บล็อกเชน เซิร์ฟเวอร์ดำเนินการลายเซ็น RSA ของรหัสเกม สัญญาอัจฉริยะจะตรวจสอบความถูกต้องของลายเซ็นและตัดสินผู้ชนะ หากเซิร์ฟเวอร์ไม่ส่งสิ่งใด ผู้ใช้จะชนะโดยอัตโนมัติ

นี่เป็นวิธีการสร้างที่ซื่อสัตย์ เนื่องจากการยักย้ายเป็นไปไม่ได้ในทางเทคนิค เกม Tradisys ทั้งหมดทำงานตามอัลกอริทึมที่อธิบายไว้ นี่คือวิธีการทำงานของเกมบล็อกเชน ทุกอย่างโปร่งใสและตรวจสอบได้ ไม่มีความคล้ายคลึงของระบบดังกล่าวในบล็อกเชนอื่น ๆ นี่เป็นการสุ่มที่ยุติธรรม

ที่มา: will.com

เพิ่มความคิดเห็น