Πώς να προσδιορίσετε τη διεύθυνση ενός έξυπνου συμβολαίου πριν από την ανάπτυξη: χρησιμοποιώντας το CREATE2 για μια ανταλλαγή κρυπτογράφησης

Το θέμα του blockchain δεν παύει να είναι πηγή όχι μόνο κάθε είδους διαφημιστικής εκστρατείας, αλλά και πολύ πολύτιμων ιδεών από τεχνολογική άποψη. Ως εκ τούτου, δεν παρέκαμψε τους κατοίκους της ηλιόλουστης πόλης. Οι άνθρωποι κοιτάζουν προσεκτικά, μελετούν, προσπαθούν να μεταφέρουν την τεχνογνωσία τους στην παραδοσιακή βάση πληροφοριών σε συστήματα blockchain. Μέχρι στιγμής, σημειακά: μία από τις εξελίξεις της Rostelecom-Solar είναι σε θέση να ελέγχει την ασφάλεια του λογισμικού που βασίζεται στο blockchain. Και στην πορεία, προκύπτουν κάποιες σκέψεις για την επίλυση εφαρμοσμένων προβλημάτων της κοινότητας του blockchain. Ένα από αυτά τα life hacks - πώς να προσδιορίσετε τη διεύθυνση ενός έξυπνου συμβολαίου πριν από την ανάπτυξη χρησιμοποιώντας το CREATE2 - σήμερα θέλω να μοιραστώ μαζί σας κάτω από την περικοπή.

Πώς να προσδιορίσετε τη διεύθυνση ενός έξυπνου συμβολαίου πριν από την ανάπτυξη: χρησιμοποιώντας το CREATE2 για μια ανταλλαγή κρυπτογράφησης
Ο κωδικός CREATE2 προστέθηκε στο hard fork της Κωνσταντινούπολης στις 28 Φεβρουαρίου φέτος. Όπως αναφέρεται στο EIP, αυτός ο κωδικός πρόσβασης εισήχθη κυρίως για κρατικά κανάλια. Ωστόσο, το χρησιμοποιήσαμε για να λύσουμε ένα διαφορετικό πρόβλημα.

Υπάρχουν χρήστες με υπόλοιπα στο χρηματιστήριο. Πρέπει να παρέχουμε σε κάθε χρήστη μια διεύθυνση Ethereum, στην οποία ο καθένας μπορεί να στείλει διακριτικά, συμπληρώνοντας έτσι τον λογαριασμό του. Ας ονομάσουμε αυτές τις διευθύνσεις «πορτοφόλια». Όταν τα κουπόνια φτάνουν σε πορτοφόλια, πρέπει να τα στείλουμε σε ένα μόνο πορτοφόλι (hotwallet).

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

Διευθύνσεις Ethereum

Η απλούστερη λύση είναι η δημιουργία νέων διευθύνσεων ethereum για νέους χρήστες. Αυτές οι διευθύνσεις θα είναι τα πορτοφόλια. Για να μεταφέρετε διακριτικά από το πορτοφόλι στο πορτοφόλι, πρέπει να υπογράψετε τη συναλλαγή καλώντας τη συνάρτηση ΜΕΤΑΦΟΡΑ() με το ιδιωτικό κλειδί του πορτοφολιού από το backend.

Αυτή η προσέγγιση έχει τα ακόλουθα πλεονεκτήματα:

  • είναι απλό
  • το κόστος μεταφοράς κουπονιών από πορτοφόλι σε πορτοφόλι είναι ίσο με το κόστος κλήσης της συνάρτησης ΜΕΤΑΦΟΡΑ()

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

Πώς να προσδιορίσετε τη διεύθυνση ενός έξυπνου συμβολαίου πριν από την ανάπτυξη: χρησιμοποιώντας το CREATE2 για μια ανταλλαγή κρυπτογράφησης

Δημιουργήστε ένα ξεχωριστό έξυπνο συμβόλαιο για κάθε χρήστη

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

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

Opcode CREATE2

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

keccak256 (0xff ++ address ++ salt ++ keccak256 (init_code)) [12:]


, όπου:

  • διεύθυνση — διεύθυνση του έξυπνου συμβολαίου που θα καλέσει το CREATE2
  • αλάτι - τυχαία τιμή
  • init_code - bytecode έξυπνου συμβολαίου για ανάπτυξη

Αυτό διασφαλίζει ότι η διεύθυνση που παρέχουμε στον χρήστη θα περιέχει πραγματικά τον επιθυμητό bytecode. Επίσης, αυτό το έξυπνο συμβόλαιο μπορεί να αναπτυχθεί όποτε το χρειαστούμε. Για παράδειγμα, όταν ένας χρήστης αποφασίζει να χρησιμοποιήσει το πορτοφόλι του για πρώτη φορά.
Πώς να προσδιορίσετε τη διεύθυνση ενός έξυπνου συμβολαίου πριν από την ανάπτυξη: χρησιμοποιώντας το CREATE2 για μια ανταλλαγή κρυπτογράφησης
Επιπλέον, μπορείτε να υπολογίζετε τη διεύθυνση έξυπνου συμβολαίου κάθε φορά αντί να την αποθηκεύετε, γιατί:

  • διεύθυνση στον τύπο είναι σταθερή καθώς είναι η διεύθυνση του εργοστασίου πορτοφολιών μας
  • αλάτι - user_id hash
  • init_code είναι μόνιμη αφού χρησιμοποιούμε το ίδιο πορτοφόλι

Περισσότερες βελτιώσεις

Η προηγούμενη λύση εξακολουθεί να έχει ένα μειονέκτημα: πρέπει να πληρώσετε για την ανάπτυξη έξυπνων συμβολαίων. Ωστόσο, μπορείτε να απαλλαγείτε από αυτό. Για αυτό μπορείτε να καλέσετε τη συνάρτηση ΜΕΤΑΦΟΡΑ()και στη συνέχεια αυτοκαταστροφή() στον κατασκευαστή πορτοφολιού. Και τότε το αέριο για την ανάπτυξη του έξυπνου συμβολαίου θα επιστραφεί.

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

Λάβετε υπόψη ότι αυτή η λύση είναι παρόμοια με τη λύση διεύθυνσης ethereum, αλλά χωρίς την ανάγκη αποθήκευσης ιδιωτικών κλειδιών. Το κόστος μεταφοράς χρημάτων από ένα πορτοφόλι σε ένα hotwallet είναι περίπου ίσο με το κόστος κλήσης μιας συνάρτησης ΜΕΤΑΦΟΡΑ(), αφού δεν πληρώνουμε για την ανάπτυξη του έξυπνου συμβολαίου.

Τελική απόφαση

Πώς να προσδιορίσετε τη διεύθυνση ενός έξυπνου συμβολαίου πριν από την ανάπτυξη: χρησιμοποιώντας το CREATE2 για μια ανταλλαγή κρυπτογράφησης

Αρχικά ετοιμάστηκε:

  • λειτουργία λήψης αλατιού user_id
  • έξυπνο συμβόλαιο που θα καλεί τον κωδικό CREATE2 με το κατάλληλο αλάτι (π.χ. εργοστάσιο πορτοφολιού)
  • bytecode πορτοφολιού που αντιστοιχεί στη σύμβαση με τον ακόλουθο κατασκευαστή:

constructor () {
    address hotWallet = 0x…;
    address token = 0x…;
    token.transfer (hotWallet, token.balanceOf (address (this)));
    selfdestruct (address (0));
}


Για κάθε νέο χρήστη, δείχνουμε τη διεύθυνση του πορτοφολιού του με υπολογισμό

keccak256 (0xff ++ address ++ salt ++ keccak256 (init_code)) [12:]


Όταν ο χρήστης μεταφέρει διακριτικά στην αντίστοιχη διεύθυνση πορτοφολιού, το backend μας βλέπει το συμβάν μεταφοράς με την παράμετρο _προς τοίσο με τη διεύθυνση του πορτοφολιού. Σε αυτό το σημείο, είναι ήδη δυνατό να αυξηθεί το υπόλοιπο του χρήστη στο χρηματιστήριο πριν από την ανάπτυξη του πορτοφολιού.

Όταν συγκεντρωθούν αρκετά token στη διεύθυνση του πορτοφολιού, μπορούμε να τα μεταφέρουμε όλα ταυτόχρονα στο hotwallet. Για να γίνει αυτό, το backend καλεί την εργοστασιακή συνάρτηση έξυπνης σύμβασης, η οποία εκτελεί τις ακόλουθες ενέργειες:

function deployWallet (соль uint256) {
    bytes memory walletBytecode =…;
    // invoke CREATE2 with wallet bytecode and salt
}


Έτσι, καλείται ο κατασκευαστής έξυπνων συμβολαίων πορτοφολιού, ο οποίος μεταφέρει όλα τα διακριτικά του στη διεύθυνση hotwallet και στη συνέχεια αυτοκαταστρέφεται.

Μπορείτε να βρείτε τον πλήρη κωδικό εδώ. Λάβετε υπόψη ότι αυτός δεν είναι ο κωδικός παραγωγής μας, καθώς αποφασίσαμε να βελτιστοποιήσουμε τον bytecode του πορτοφολιού και να τον γράψουμε σε opcodes.

Συγγραφέας Pavel Kondratenkov, ειδικός στο Ethereum

Πηγή: www.habr.com

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