Επικύρωση ενοποιημένης διεύθυνσης (ZIP-316)
Αυτός είναι ένας οδηγός εκμάθησης, όχι ένας έτοιμος αποκωδικοποιητής ή βιβλιοθήκη πληρωμών για αντιγραφή-επικόλληση. Εξηγεί πώς είναι δομημένη η ενοποιημένη διεύθυνση ώστε να μπορείς να κατανοήσεις τι κάνουν στο παρασκήνιο οι συντηρούμενες βιβλιοθήκες. Για οτιδήποτε διαχειρίζεται πραγματικά κεφάλαια, ακολούθησε την προδιαγραφή ZIP-316 και τις επίσημες υλοποιήσεις που συνδέονται παρακάτω.
Η γενική εικόνα
Μια ενοποιημένη διεύθυνση (UA) είναι μια ενιαία συμβολοσειρά διεύθυνσης που περιέχει πολλαπλούς τύπους δεκτών: Διαφανείς, Sapling, Orchard ή έναν συνδυασμό αυτών. Το πορτοφόλι που εκτελεί την πληρωμή επιλέγει αυτόματα το καλύτερο pool δεκτών που υποστηρίζει.
Σκέψου μια UA ως έναν σφραγισμένο φάκελο που περιέχει αρκετές κάρτες με ετικέτες. Κάθε κάρτα αντιπροσωπεύει έναν διαφορετικό τρόπο για να σε προσεγγίσει κάποιος. Για να ελέγξει μια διεύθυνση, μια εφαρμογή πρέπει να:
- Ανοίξει τον φάκελο: Αποκωδικοποιήσει τη συμβολοσειρά κειμένου.
- Αναιρέσει την ανακάτεψη του περιεχομένου: Αναιρέσει την προστατευτική ανακάτεψη (F4Jumble).
- Διαβάσει κάθε κάρτα: Εξαγάγει τους μεμονωμένους παραλήπτες.
- Εφαρμόσει τους κανόνες του πρωτοκόλλου: Αγνοήσει ή απορρίψει καταχωρίσεις ανάλογα με το εύρος του typecode τους.
Γιατί δεν αρκεί «απλώς αποκωδικοποίησε Bech32m»
Μια UA χρησιμοποιεί κωδικοποίηση κειμένου Bech32m, αλλά η αποκωδικοποίηση μόνο του Bech32m δεν αποκαλύπτει τους χρησιμοποιήσιμους παραλήπτες.
Το ZIP-316 ανακατεύει σκόπιμα το payload χρησιμοποιώντας F4Jumble πριν από την κωδικοποίηση. Το F4Jumble εξασφαλίζει ότι η αλλαγή ακόμη και ενός μόνο χαρακτήρα στη διεύθυνση αλλάζει πλήρως το αποκωδικοποιημένο αποτέλεσμα. Αυτό αποτρέπει επιθέσεις μεταβλητότητας διεύθυνσης, όπου ένας επιτιθέμενος αντικαθιστά bytes στη μέση μιας διεύθυνσης, ενώ το πρόθεμα και το επίθεμα εξακολουθούν να φαίνονται έγκυρα.
Βασικός κανόνας: Η προστασία από μεταβλητότητα λειτουργεί μόνο αν η εφαρμογή σου εκτελεί την πλήρη διαδικασία αποκωδικοποίησης και επικύρωσης. Η μερική αποκωδικοποίηση αφαιρεί την ασφάλεια ενώ διατηρεί όλο το ρίσκο.
Η διαδικασία αποκωδικοποίησης, βήμα προς βήμα
Βήμα 1: Αποκωδικοποίησε Bech32m και έλεγξε το δίκτυο
- Αναγνώσιμο από ανθρώπους μέρος (HRP): Το
u προσδιορίζει το mainnet· το utest προσδιορίζει το testnet. (Οι UA του mainnet αρχίζουν με u1, όπου το 1 είναι ο διαχωριστής Bech32.)
- Όριο μήκους: Το τυπικό Bech32m επιβάλλει όριο 90 χαρακτήρων. Οι UA συνήθως υπερβαίνουν αυτό το όριο, επομένως οι τυπικοί έλεγχοι μήκους πρέπει να απενεργοποιούνται στον αποκωδικοποιητή.
- Μετέτρεψε τις λέξεις Bech32m των 5 bit ξανά σε τυπικά bytes των 8 bit.
Βήμα 2: Αντιστροφή του F4Jumble
Το F4Jumble είναι ένα δίκτυο Feistel 4 γύρων βασισμένο στο BLAKE2b:
- Μήκος αριστερού μισού:
min(64, floor(length / 2)) bytes. Το όριο των 64 bytes αντιστοιχεί στο μέγιστο μέγεθος εξόδου του BLAKE2b. Το δεξί μισό περιέχει το υπόλοιπο payload.
- Συναρτήσεις κατακερματισμού: Εναλλάσσει τις G και H χρησιμοποιώντας σταθερές ετικέτες εξατομίκευσης (
UA_F4Jumble_G και UA_F4Jumble_H).
- Σειρά γύρων: Η προώθηση της κωδικοποίησης εκτελεί G(0) → H(0) → G(1) → H(1). Η αντιστροφή της (ανακάτεψη προς τα πίσω) εκτελεί H(1) → G(1) → H(0) → G(0).
- Έλεγχος εύρους: Απόρριψε εισόδους εκτός των ορίων μεγέθους payload του ZIP-316.
Βήμα 3: Αφαίρεσε τη συμπλήρωση και επαλήθευσε το HRP
Πριν από την ανακάτεψη, ο κωδικοποιητής προσθέτει 16 bytes που περιέχουν το HRP, συμπληρωμένα με μηδενικά.
- Αφαίρεσε τα τελευταία 16 bytes μετά την ανακάτεψη προς τα πίσω.
- Επιβεβαίωσε ότι το ενσωματωμένο HRP αντιστοιχεί στο αναμενόμενο δίκτυο (
u ή utest). Αυτό αποτρέπει την κατά λάθος αποδοχή διευθύνσεων testnet στο mainnet.
Βήμα 4: Εξήγαγε παραλήπτες
Το υπόλοιπο payload αποτελείται από καταχωρίσεις (typecode, length, content), όπου το typecode και το μήκος αποθηκεύονται ως ακέραιοι compact-size (ένα μόνο byte για μικρές τιμές). Γνωστά typecode παραληπτών:
| Κωδικός τύπου | Τύπος παραλήπτη | Μήκος περιεχομένου |
|---|
0x00 | Διαφανές (P2PKH) | 20 bytes |
0x01 | Διαφανές (P2SH) | 20 bytes |
0x02 | Sapling | 43 bytes |
0x03 | Orchard | 43 bytes |
Πέρα από αυτούς, το ZIP-316 δεσμεύει δύο επιπλέον εύρη για μελλοντική συμβατότητα:
0xC0–0xDF (μεταδεδομένα χωρίς MUST-understand): Οι εφαρμογές πρέπει να αγνοούν στοιχεία μεταδεδομένων που δεν αναγνωρίζουν σε αυτό το εύρος.
0xE0 και 0xE1 (εκχωρημένα μεταδεδομένα λήξης MUST-understand): Το τρέχον μητρώο του ZIP-316 τα εκχωρεί στο ύψος και τον χρόνο λήξης της διεύθυνσης. Οι εφαρμογές πρέπει να κατανοούν αυτά τα στοιχεία ή να απορρίπτουν τη διεύθυνση.
0xE2–0xFC (μη εκχωρημένα μεταδεδομένα MUST-understand): Οι εφαρμογές πρέπει να απορρίπτουν τη διεύθυνση αν συναντήσουν ένα μη αναγνωρισμένο στοιχείο σε αυτό το εύρος.
Για γνωστούς τύπους παραληπτών, επαλήθευσε ότι το κωδικοποιημένο μήκος αντιστοιχεί στο καθορισμένο μήκος περιεχομένου του τύπου. Για στοιχεία μεταδεδομένων, χρησιμοποίησε το κωδικοποιημένο μήκος compact-size για να προσδιορίσεις το μήκος του περιεχομένου. Απόρριψε περικομμένες καταχωρίσεις ή τυχόν τελικά bytes.
Προτιμώμενη σειρά παραληπτών. Μόλις μια διεύθυνση αναλυθεί επιτυχώς, ένα πορτοφόλι ή εργαλείο πληρωμών πρέπει να επιλέγει τον καλύτερο παραλήπτη με αυτή τη σειρά: Orchard, έπειτα Sapling, έπειτα διαφανές.
Υποχρεωτικοί κανόνες απόρριψης του ZIP-316
Η επιτυχής αποκωδικοποίηση δεν καθιστά μια διεύθυνση έγκυρη. Τα επίσημα πορτοφόλια Zcash απορρίπτουν αυστηρά διευθύνσεις που παραβιάζουν τους ακόλουθους κανόνες. Τα εργαλεία web πρέπει επίσης να τις απορρίπτουν, ώστε να αποτρέπονται αποτυχίες πληρωμών:
- Απουσία θωρακισμένων παραληπτών: Η διεύθυνση πρέπει να περιέχει τουλάχιστον έναν παραλήπτη Sapling ή Orchard. Μια UA μόνο με διαφανείς παραλήπτες είναι άκυρη σύμφωνα με το ZIP-316.
- Διπλότυπα typecode: Κάθε τύπος παραλήπτη μπορεί να εμφανίζεται το πολύ μία φορά.
- Μη ταξινομημένα typecode: Οι παραλήπτες πρέπει να εμφανίζονται σε αυστηρά αύξουσα σειρά typecode.
- Αντικρουόμενοι διαφανείς παραλήπτες: Μια UA μπορεί να περιέχει είτε P2PKH είτε P2SH, αλλά ποτέ και τα δύο.
- Κακόμορφες καταχωρίσεις ή συμπλήρωση: Ασυμφωνίες προθεμάτων δικτύου, περικομμένα payload ή ασυμφωνίες μήκους πρέπει να ενεργοποιούν άμεση απόρριψη.
- Μη αναγνωρισμένα typecode: Οι εφαρμογές πρέπει να αγνοούν μη αναγνωρισμένα στοιχεία, εκτός από στοιχεία στο εύρος μεταδεδομένων MUST-understand (
0xE0–0xFC), τα οποία πρέπει να απορρίπτουν όταν δεν αναγνωρίζονται. Στο τρέχον μητρώο, τα 0xE0 και 0xE1 είναι εκχωρημένοι τύποι λήξης, ενώ τα 0xE2–0xFC δεν είναι εκχωρημένα. Ανεξάρτητα από αυτό, απόρριψε κάθε διεύθυνση που αποτυγχάνει στους παραπάνω υποχρεωτικούς κανόνες εγκυρότητας, συμπεριλαμβανομένης της απαίτησης για παραλήπτη Sapling ή Orchard.
Βέλτιστες πρακτικές για προγραμματιστές
- Σύγκρινε αναλυμένους παραλήπτες, όχι ακατέργαστες συμβολοσειρές. Αποκωδικοποίησε πρώτα τις διευθύνσεις πριν ελέγξεις την ισότητα.
- Χρησιμοποίησε συντηρούμενες βιβλιοθήκες για οτιδήποτε διαχειρίζεται κεφάλαια. Μετέτρεψε σε WebAssembly τα επίσημα crates Rust (όπως το
zcash_address), αντί να αναπτύξεις προσαρμοσμένους αποκωδικοποιητές JavaScript.
- Να είσαι προσεκτικός με χειρόγραφα parsers. Αν γράψεις έναν για να μάθεις, αντιμετώπισέ τον ως έργο μελέτης και δοκίμασέ τον με τα επίσημα vectors παρακάτω πριν τον εμπιστευτείς για οτιδήποτε.
Επίσημες προδιαγραφές και υλοποιήσεις αναφοράς
Γλωσσάρι
| Όρος | Σημασία |
|---|
| Unified Address (UA) | Ενιαία συμβολοσειρά διεύθυνσης που συνδυάζει πολλαπλά pool δεκτών. |
| Receiver | Συγκεκριμένος τύπος προορισμού πληρωμής (διαφανές, Sapling ή Orchard). |
| Bech32m | Σχήμα κωδικοποίησης κειμένου που χρησιμοποιείται για συμβολοσειρές UA. |
| HRP | Αναγνώσιμο από ανθρώπους μέρος ή πρόθεμα δικτύου (u ή utest). |
| F4Jumble | Αναστρέψιμος αλγόριθμος απόκρυψης που εξασφαλίζει την ακεραιότητα της διεύθυνσης. |
| Typecode | Αριθμός σε κάθε καταχώριση που ορίζει τον τύπο παραλήπτη στο payload. |
| Malleability | Μη εξουσιοδοτημένη τροποποίηση των bytes μιας διεύθυνσης χωρίς ανίχνευση. |
Δες επίσης: Viewing Keys