RSA τυχαία σε blockchain

Υπάρχει ένα πρόβλημα - είναι δύσκολο να δημιουργηθεί ένας τυχαίος αριθμός σε ένα αποκεντρωμένο δίκτυο. Σχεδόν όλα τα blockchain το έχουν ήδη αντιμετωπίσει. Πράγματι, σε δίκτυα όπου δεν υπάρχει εμπιστοσύνη μεταξύ των χρηστών, η δημιουργία ενός αναμφισβήτητου τυχαίου αριθμού λύνει πολλά προβλήματα.

Σε αυτό το άρθρο σας λέμε πώς καταφέραμε να λύσουμε το πρόβλημα χρησιμοποιώντας ως παράδειγμα παιχνίδια. Το πρώτο από αυτά ήταν Κύματα Χριστουγεννιάτικο δέντρο. Για ανάπτυξη, χρειαζόμασταν μια γεννήτρια τυχαίων αριθμών.

RSA τυχαία σε blockchain

Αρχικά, σχεδιάζαμε να δημιουργήσουμε έναν αριθμό με βάση πληροφορίες από το blockchain. Ωστόσο, στη συνέχεια έγινε σαφές: ο αριθμός θα μπορούσε να χειραγωγηθεί, πράγμα που σημαίνει ότι η λύση δεν είναι κατάλληλη.

Καταλήξαμε σε μια λύση: χρησιμοποιήστε το σχήμα δέσμευσης-επέκτασης. Ο διακομιστής μάντεψε έναν αριθμό από το 1 έως το 5, πρόσθεσε ένα αλάτι σε αυτόν και στη συνέχεια κατακερματίστηκε το αποτέλεσμα χρησιμοποιώντας Λειτουργίες Keccak. Ο διακομιστής ανέπτυξε το έξυπνο συμβόλαιο με τον ήδη αποθηκευμένο αριθμό εκ των προτέρων. Αποδεικνύεται ότι το παιχνίδι καταλήγει στο να μαντέψει ο χρήστης τον αριθμό που κρύβεται από τον κατακερματισμό.

Ο παίκτης έβαλε ένα στοίχημα και ο διακομιστής έστειλε τον κρυφό αριθμό και το "αλάτι" στο έξυπνο συμβόλαιο. Με απλά λόγια, αποκάλυψε τα χαρτιά. Μετά από αυτό, ο διακομιστής έλεγξε τους αριθμούς και αποφάσισε αν ο χρήστης κέρδισε ή έχασε.

Εάν ο διακομιστής δεν έστειλε έναν αριθμό ή "αλάτι" για επαλήθευση, ο χρήστης κέρδισε. Σε αυτήν την περίπτωση, για κάθε παιχνίδι ήταν απαραίτητο να αναπτυχθεί ένα έξυπνο συμβόλαιο εκ των προτέρων και να συμπεριληφθούν πιθανά κέρδη σε αυτό. Αποδείχθηκε ότι ήταν άβολο, χρονοβόρο και ακριβό. Τότε δεν υπήρχε άλλη ασφαλής λύση.

Πρόσφατα, η ομάδα Tradisys πρότεινε την προσθήκη μιας συνάρτησης στο πρωτόκολλο Waves rsaVerify(). Ελέγχει την εγκυρότητα της υπογραφής RSA με βάση το δημόσιο και ιδιωτικό κλειδί. Ως αποτέλεσμα, προστέθηκε η δυνατότητα.

Έχουμε αναπτύξει τρία παιχνίδια: Κύλινδρος ζαριών, Coin Flip и Ride On Waves. Κάθε ένα εφαρμόζει τεχνολογία τυχαίων αριθμών. Ας καταλάβουμε πώς λειτουργεί.

RSA τυχαία σε blockchain

Ας δούμε τη δημιουργία ενός τυχαίου αριθμού χρησιμοποιώντας το Ride on Waves ως παράδειγμα. Το έξυπνο συμβόλαιο μπορεί να βρεθεί εδώ.

Μεταβείτε στην καρτέλα Γραφή και επιλέξτε Απομεταγλωττισμένο. Θα δείτε τον κωδικό έξυπνου συμβολαίου (γνωστός και ως σενάριο).

RSA τυχαία σε blockchain

Ο κωδικός έξυπνου συμβολαίου περιέχει ένα σύνολο λειτουργιών. Αυτά που έχουν επισημανθεί ως @Callable μπορούν να εκκινηθούν χρησιμοποιώντας Συναλλαγές επίκλησης. Μας ενδιαφέρουν δύο λειτουργίες: στοίχημα и αποσύρω:

  • στοίχημα func (playerChoice)
  • απόσυρση func (gameId,rsaSign)

1. Ο χρήστης επιλέγει το μήκος του τμήματος και το μέγεθος του στοιχήματος.

RSA τυχαία σε blockchain

2. Ο πελάτης δημιουργεί μια συνάρτηση στοιχήματος. Για την παραπάνω εικόνα θα ήταν στοίχημα ("50").

3. Ο πελάτης στέλνει μια συναλλαγή Invocation στη διεύθυνση έξυπνου συμβολαίου (broadcast InvocationTx). Η συναλλαγή περιέχει τη συνάρτηση στοιχήματος ως παράμετρο κλήσης. Αυτό σημαίνει ότι η συναλλαγή Invocation ενεργοποιεί την εκτέλεση της συνάρτησης στοιχήματος (επιλογή: String) στο έξυπνο συμβόλαιο.

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

Έτσι μοιάζει μια εγγραφή δεδομένων στο blockchain (κλειδί-τιμή):

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

"Κλειδί" (κλειδί) - αναγνωριστικό παιχνιδιού νέο παιχνίδι. Τα υπόλοιπα δεδομένα περιέχονται στη γραμμή του πεδίου "τιμή". Αυτές οι καταχωρήσεις αποθηκεύονται στην καρτέλα ημερομηνία έξυπνο συμβόλαιο:

RSA τυχαία σε blockchain

RSA τυχαία σε blockchain

5. Ο διακομιστής «κοιτάζει» το έξυπνο συμβόλαιο και βρίσκει την απεσταλμένη συναλλαγή (νέο παιχνίδι) χρησιμοποιώντας το blockchain Api. Το αναγνωριστικό παιχνιδιού του νέου παιχνιδιού έχει ήδη καταγραφεί στο blockchain, πράγμα που σημαίνει ότι δεν μπορεί πλέον να αλλάξει ή να επηρεαστεί

6. Ο διακομιστής δημιουργεί μια συνάρτηση απόσυρσης (gameId, rsaSign). Για παράδειγμα, όπως αυτό:

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

7. Ο διακομιστής στέλνει μια συναλλαγή Invocation στο smart contract (broadcast InvocationTx). Η συναλλαγή περιέχει μια κλήση προς τη σχηματισμένη συνάρτηση ανάληψης (gameId, rsaSign):

RSA τυχαία σε blockchain

Η συνάρτηση περιέχει αναγνωριστικό παιχνιδιού νέο παιχνίδι και το αποτέλεσμα της υπογραφής RSA ενός μοναδικού αναγνωριστικού με ιδιωτικό κλειδί. Το αποτέλεσμα της υπογραφής παραμένει αμετάβλητο.

Τι σημαίνει αυτό;

Παίρνουμε την ίδια τιμή (αναγνωριστικό παιχνιδιού) και εφαρμόζουμε τη μέθοδο υπογραφής RSA σε αυτήν. Θα έχουμε πάντα το ίδιο αποτέλεσμα. Έτσι λειτουργεί ο αλγόριθμος RSA. Δεν είναι δυνατός ο χειρισμός του τελικού αριθμού, καθώς το αναγνωριστικό του παιχνιδιού και το αποτέλεσμα της εφαρμογής RSA δεν είναι γνωστά. Η επιλογή ενός αριθμού είναι επίσης άσκοπη.

8. Το Blockchain αποδέχεται τη συναλλαγή. Εκτελεί τη λειτουργία απόσυρσης (gameId, rsaSign)

9. Μέσα στη λειτουργία απόσυρσης, πραγματοποιείται απόσυρση GenerateRandInt συναρτήσεις (gameId, 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 μεταβιβάζονται στην είσοδο. Η υπογραφή ελέγχεται για εγκυρότητα. Ο αριθμός δημιουργείται εάν ο έλεγχος είναι επιτυχής. Διαφορετικά, το σύστημα θεωρεί ότι η υπογραφή δεν είναι έγκυρη (Invalid RSA signature).

Ο διακομιστής πρέπει να υπογράψει το αναγνωριστικό του παιχνιδιού με ένα ιδιωτικό κλειδί και να στείλει μια έγκυρη υπογραφή Rsa εντός 2880 μπλοκ. Η παράμετρος διαμορφώνεται κατά την ανάπτυξη του έξυπνου συμβολαίου. Εάν δεν συμβεί τίποτα εντός του καθορισμένου χρόνου, ο χρήστης κερδίζει. Σε αυτή την περίπτωση, το έπαθλο πρέπει να αποσταλεί μόνος σας στη διεύθυνσή σας. Αποδεικνύεται ότι "δεν είναι κερδοφόρο για τον διακομιστή να εξαπατήσει", επειδή αυτό οδηγεί σε απώλεια. Παρακάτω είναι ένα παράδειγμα.

RSA τυχαία σε blockchain

Ο χρήστης παίζει Κύλινδρος ζαριών. Διάλεξα 2 από τις 6 πλευρές του κύβου, το στοίχημα είναι 14 ΚΥΜΑΤΑ. Εάν ο διακομιστής δεν στείλει έγκυρη υπογραφή RSA στο έξυπνο συμβόλαιο εντός του καθορισμένου χρόνου (2880 μπλοκ), ο χρήστης θα λάβει 34.44 ΚΥΜΑΤΑ.

Για να δημιουργήσουμε αριθμούς στα παιχνίδια, χρησιμοποιούμε ένα μαντείο - ένα εξωτερικό σύστημα που δεν είναι blockchain. Ο διακομιστής εκτελεί μια υπογραφή RSA του αναγνωριστικού παιχνιδιού. Το έξυπνο συμβόλαιο ελέγχει την εγκυρότητα της υπογραφής και καθορίζει τον νικητή. Εάν ο διακομιστής δεν στείλει τίποτα, τότε ο χρήστης κερδίζει αυτόματα.

Αυτή είναι μια ειλικρινής μέθοδος παραγωγής, γιατί η χειραγώγηση είναι τεχνικά αδύνατη. Όλα τα παιχνίδια Tradisys λειτουργούν με βάση τον περιγραφόμενο αλγόριθμο. Έτσι λειτουργούν τα παιχνίδια blockchain. Όλα είναι διαφανή και επαληθεύσιμα. Δεν υπάρχουν ανάλογα ενός τέτοιου συστήματος σε κανένα άλλο blockchain. Αυτό είναι ένα δίκαιο τυχαίο.

Πηγή: www.habr.com

Προσθέστε ένα σχόλιο