Blockchain дээрх RSA санамсаргүй

Асуудал бий - төвлөрсөн бус сүлжээнд санамсаргүй тоо үүсгэх нь хэцүү байдаг. Бараг бүх блокчэйн ийм асуудалтай тулгарсан. Үнэн хэрэгтээ хэрэглэгчдийн хооронд итгэлцэл байхгүй сүлжээнд маргаангүй санамсаргүй тоог бий болгох нь олон асуудлыг шийддэг.

Энэ нийтлэлд бид жишээ болгон тоглоом ашиглан асуудлыг хэрхэн шийдэж чадсаныг танд хэлэх болно. Тэдний эхнийх нь байсан Зул сарын гацуур мод. Хөгжүүлэхийн тулд бидэнд санамсаргүй тоо үүсгэгч хэрэгтэй байсан.

Blockchain дээрх RSA санамсаргүй

Бид эхний ээлжинд блокчэйний мэдээлэлд тулгуурлан тоо гаргахаар төлөвлөж байсан. Гэсэн хэдий ч дараа нь тодорхой болсон: дугаарыг удирдаж болно, энэ нь шийдэл нь тохиромжгүй гэсэн үг юм.

Бид тойрон гарах арга замыг олсон: commit-expand схемийг ашигла. Сервер 1-ээс 5 хүртэлх тоог тааж, давс нэмээд үр дүнг ашиглан хэш хийсэн Keccak функцууд. Сервер нь аль хэдийн хадгалсан дугаартай ухаалаг гэрээг урьдчилан байршуулсан. Хэрэглэгч хэшээр нуугдаж буй тоог таахад л тоглоом унтдаг болох нь харагдаж байна.

Тоглогч бооцоо тавьсан бөгөөд сервер нь далд дугаар болон "давс"-ыг ухаалаг гэрээ рүү илгээсэн. Энгийнээр хэлэхэд тэр хөзрүүдийг илчилсэн. Үүний дараа сервер тоонуудыг шалгаад хэрэглэгч хожсон уу, хожигдсон уу гэдгийг шийдэв.

Хэрэв сервер баталгаажуулахын тулд дугаар эсвэл "давс" илгээгээгүй бол хэрэглэгч ялсан. Энэ тохиолдолд тоглоом бүрийн хувьд ухаалаг гэрээг урьдчилан байрлуулж, түүнд боломжит ялалтыг оруулах шаардлагатай байв. Энэ нь эвгүй, цаг хугацаа их шаарддаг, үнэтэй байсан. Тэр үед өөр аюулгүй шийдэл байгаагүй.

Саяхан Tradisys баг Waves протоколд функц нэмэхийг санал болгов rsaVerify(). Энэ нь нийтийн болон хувийн түлхүүр дээр үндэслэн RSA гарын үсгийн хүчинтэй эсэхийг шалгадаг. Үүний үр дүнд функц нэмэгдсэн.

Бид гурван тоглоом боловсруулсан: Шоо Roller, Зоосон мөнгө и Ride on Waves. Тус бүр нь санамсаргүй тооны технологийг хэрэгжүүлдэг. Энэ нь хэрхэн ажилладагийг олж мэдье.

Blockchain дээрх RSA санамсаргүй

Ride on Waves ашиглан санамсаргүй тоо үүсгэхийг жишээ болгон авч үзье. Ухаалаг гэрээг олж болно энд.

Таб руу очно уу Script мөн сонгоно уу Эмхэтгэсэн. Та ухаалаг гэрээний кодыг (скрипт гэх мэт) харах болно.

Blockchain дээрх RSA санамсаргүй

Ухаалаг гэрээний код нь олон тооны функцуудыг агуулдаг. @Callable гэж тэмдэглэгдсэн хүмүүсийг ашиглан эхлүүлж болно Дуудлага хийх гүйлгээ. Бид хоёр функцийг сонирхож байна: бооцоо и буцах:

  • func бооцоо (тоглогчийн сонголт)
  • функцийг татах(тоглоомын дугаар, rsaSign)

1. Хэрэглэгч сегментийн урт болон бооцооны хэмжээг сонгоно.

Blockchain дээрх RSA санамсаргүй

2. Үйлчлүүлэгч нь бооцооны функцийг үүсгэдэг. Дээрх зургийн хувьд ийм байх болно бооцоо("50").

3. Үйлчлүүлэгч Ухаалаг гэрээний хаяг руу Invocation гүйлгээг илгээдэг (InvocationTx нэвтрүүлэг). Гүйлгээ нь дуудлагын параметр болгон бооцооны функцийг агуулдаг. Энэ нь Дуудлага гүйлгээ нь ухаалаг гэрээн дээрх бооцооны функцийг (сонголт: Мөр) гүйцэтгэхийг өдөөдөг гэсэн үг юм.

Blockchain дээрх RSA санамсаргүй

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

Уг функц нь ухаалаг гэрээний төлөвт шинэ тоглоом бичдэг. Тухайлбал:

  • Шинэ тоглоомын өвөрмөц танигч (тоглоомын ID)
  • Тоглоомын төлөв = ИЛГЭЭЛЭЭ
  • Тоглогчийн сонголт (сегментийн урт 50)
  • Нийтийн түлхүүр
  • Боломжит ялалт (тоглогчийн бооцооноос хамаарч)

Blockchain дээрх RSA санамсаргүй

Блокчэйн дэх өгөгдлийн бичлэг иймэрхүү харагдаж байна (түлхүүр утга):

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

"Түлхүүр" (түлхүүр) - тоглоомын ID шинэ тоглоом. Үлдсэн өгөгдлийг "утга" талбарын мөрөнд оруулсан болно. Эдгээр оруулгууд нь таб дээр хадгалагдана Өгөгдөл ухаалаг гэрээ:

Blockchain дээрх RSA санамсаргүй

Blockchain дээрх RSA санамсаргүй

5. Сервер ухаалаг гэрээг "харж" блокчейн Api ашиглан илгээсэн гүйлгээг (шинэ тоглоом) олдог. Шинэ тоглоомын Тоглоомын ID нь блокчэйнд аль хэдийн бичигдсэн байгаа бөгөөд энэ нь цаашид өөрчлөх, нөлөөлөх боломжгүй гэсэн үг юм.

6. Сервер нь буцаах функцийг (gameId, rsaSign) үүсгэдэг. Жишээлбэл, иймэрхүү:

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

7. Сервер нь Ухаалаг гэрээ рүү (InvocationTx нэвтрүүлэг) Invocation гүйлгээг илгээдэг. Гүйлгээ нь үүссэн татах функц (gameId, rsaSign) руу залгасан дуудлагыг агуулна.

Blockchain дээрх RSA санамсаргүй

Функц нь агуулдаг тоглоомын ID шинэ тоглоом ба хувийн түлхүүр бүхий өвөрмөц танигчтай RSA гарын үсэг зурсны үр дүн. Гарын үсгийн үр дүн өөрчлөгдөөгүй.

Энэ нь юу гэсэн үг вэ?

Бид ижил утгыг (тоглоомын id) авч, түүнд RSA гарын үсгийн аргыг ашигладаг. Бид үргэлж ижил үр дүнд хүрэх болно. RSA алгоритм ингэж ажилладаг. Тоглоомын id болон RSA-г хэрэглэсний үр дүн тодорхойгүй тул эцсийн тоог өөрчлөх боломжгүй. Тоо сонгох нь бас утгагүй юм.

8. Блокчейн нь гүйлгээг хүлээн зөвшөөрдөг. Энэ нь буцаах функцийг ажиллуулдаг (gameId, rsaSign)

9. Татах функцийн дотор татан авалт үүсдэг GenerateRandInt функцууд (тоглоомын дугаар, 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 гарын үсгийн үр дүн болох мөрийг авдаг тоглоомын ID хувийн түлхүүр (rsaSign). Дараа нь SHA-256 (sha256(rsaSign)).

Гарын үсэг болон дараагийн хэшний үр дүнг бид урьдчилан таамаглах боломжгүй. Тиймээс санамсаргүй тоо үүсгэхэд нөлөөлөх боломжгүй юм. Тодорхой мужид (жишээ нь 1-ээс 100 хүртэл) тоо авахын тулд toInt хувиргах функц болон % 100 (үүнтэй төстэй) ашиглана уу. мод).

Өгүүллийн эхэнд бид функцийг дурдсан rsaVerify(), энэ нь RSA гарын үсгийн хүчинтэй эсэхийг хувийн түлхүүр ашиглан нийтийн гарын үсгийн эсрэг шалгах боломжийг олгодог. Энд GenerateRandInt(gameId,rsaSign) хэсэг байна:

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

RSAPUBLIC нийтийн түлхүүр болон rsaSign мөрийг оролт руу дамжуулдаг. Гарын үсэг хүчинтэй эсэхийг шалгана. Шалгалт амжилттай болсон тохиолдолд дугаар үүсгэгдэнэ. Үгүй бол систем гарын үсгийг хүчингүй гэж үздэг (RSA гарын үсэг хүчингүй).

Сервер нь хувийн түлхүүрээр тоглоомын ID-д гарын үсэг зурж, 2880 блок дотор хүчинтэй Rsa гарын үсэг илгээх ёстой. Ухаалаг гэрээг байршуулах үед параметрийг тохируулна. Хэрэв заасан хугацаанд юу ч болоогүй бол хэрэглэгч ялна. Энэ тохиолдолд шагналыг өөрийн хаягаар өөрөө илгээх ёстой. Энэ нь алдагдалд хүргэдэг тул "серверийг хуурах нь ашиггүй" болж байна. Доорх жишээг үзүүлэв.

Blockchain дээрх RSA санамсаргүй

Хэрэглэгч тоглож байна Шоо Roller. Би шооны 2 талаас 6-ыг нь сонгосон, бооцоо нь 14 ДОЛГОО. Хэрэв сервер заасан хугацаанд (2880 блок) ухаалаг гэрээнд хүчинтэй RSA гарын үсгийг илгээхгүй бол хэрэглэгч 34.44 WAVES авах болно.

Тоглоомонд тоо үүсгэхийн тулд бид oracle ашигладаг - гадаад, блокчлонгүй систем. Сервер нь тоглоомын ID-н RSA гарын үсэг зурдаг. Ухаалаг гэрээ нь гарын үсгийн хүчинтэй эсэхийг шалгаж, ялагчийг тодорхойлдог. Хэрэв сервер юу ч илгээгээгүй бол хэрэглэгч автоматаар ялна.

Техникийн хувьд манипуляци хийх боломжгүй тул энэ бол шударга үеийн арга юм. Бүх Tradisys тоглоомууд тайлбарласан алгоритм дээр тулгуурлан ажилладаг. Блокчейн тоглоомууд ингэж ажилладаг. Бүх зүйл ил тод, шалгах боломжтой. Бусад блокчэйнд ийм системийн аналог байхгүй. Энэ бол шударга санамсаргүй тохиолдол юм.

Эх сурвалж: www.habr.com

сэтгэгдэл нэмэх