Επισκόπηση

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

Αναπτύσσετε μια υπηρεσία; Μεταβείτε στον οδηγό χειριστή. Ενσωματώνετε μια υπάρχουσα υπηρεσία; Μεταβείτε στο Quickstart. Αυτή η σελίδα αποτελεί την αρχιτεκτονική αναφορά και για τις δύο ομάδες.

Αρχιτεκτονική

Το Private Channels αποτελείται από τέσσερα συστατικά: δύο on-chain προγράμματα Solana (Escrow και Withdraw) και δύο off-chain υπηρεσίες (Gateway και Auth Service). Μαζί σχηματίζουν ένα πρωτόκολλο state channel όπου τα κεφάλαια βρίσκονται στο Mainnet αλλά οι μεταφορές διακανονίζονται off-chain.

Πρόγραμμα Escrow

Το Πρόγραμμα Escrow είναι ένα on-chain πρόγραμμα Solana που διατηρεί κατατεθειμένα SPL tokens. Αποτελεί την αγκυροβολία εμπιστοσύνης του συστήματος: όλα τα κεφάλαια βρίσκονται τελικά σε escrow έως ότου ένας χειριστής παράσχει έγκυρη απόδειξη αποκλεισμού Sparse Merkle Tree για να τα αποδεσμεύσει.

  • Program ID: 9tgHa1DcnaSSUtmMsst8ovKTe1Gfxzezn27KnH9xXYeU
  • Αυτό το ID μεταγλωττίζεται στο δυαδικό αρχείο του προγράμματος μέσω declare_id!(). Οι off-chain υπηρεσίες διαβάζουν το ίδιο ID κατά τη μεταγλώττιση από το παραγόμενο client crate, όχι από μεταβλητή περιβάλλοντος.
  • Διαχειρίζεται τα PDAs Instance, AllowedMint και Operator
  • Εντολές: CreateInstance, AllowMint, BlockMint, AddOperator, RemoveOperator, SetNewAdmin, Deposit, ReleaseFunds, ResetSmtRoot

Πρόγραμμα Withdraw

Το Πρόγραμμα Withdraw εκτελείται στο δίκτυο του private channel, όχι στο Solana Mainnet. Οι χρήστες καλούν WithdrawFunds για να κάψουν το υπόλοιπο token από την πλευρά του καναλιού. Αυτό το κάψιμο δεν αποδεσμεύει αυτόματα τα κεφάλαια· σηματοδοτεί στον χειριστή ότι μια ανάληψη εκκρεμεί. Ο χειριστής στη συνέχεια καλεί ReleaseFunds στο Πρόγραμμα Escrow με έγκυρη απόδειξη SMT για να ολοκληρώσει τον διακανονισμό.

  • Program ID: J231K9UEpS4y4KAPwGc4gsMNCjKFRMYcQBcjVW7vBhVi
  • Αυτό το ID μεταγλωττίζεται στο δυαδικό αρχείο του προγράμματος. Οι off-chain υπηρεσίες διαβάζουν το ίδιο ID κατά τη μεταγλώττιση από το παραγόμενο client crate, όχι από μεταβλητή περιβάλλοντος.

Gateway

Το Gateway είναι ένας proxy συμβατός με Solana JSON-RPC που δρομολογεί αιτήματα πελατών στον κόμβο εγγραφής (για υποβολή συναλλαγών) και στον κόμβο ανάγνωσης (για ερωτήματα) του δικτύου καναλιού. Διαμορφώνεται μέσω μεταβλητών περιβάλλοντος: GATEWAY_PORT, GATEWAY_WRITE_URL, GATEWAY_READ_URL.

Endpoints υγείας (δεν απαιτείται πιστοποίηση):

  • GET /health - έλεγχος liveness· επιστρέφει 200 {"status":"ok"}
  • GET /ready - βαθύς έλεγχος ετοιμότητας, δοκιμάζει τους κόμβους εγγραφής και ανάγνωσης· επιστρέφει 200 {"status":"ready"} ή 503 {"status":"degraded"}

Δρομολόγηση Μεθόδων RPC και Πρόσβαση

Το gateway δρομολογεί το sendTransaction στον κόμβο εγγραφής και όλες τις άλλες μεθόδους στον κόμβο ανάγνωσης. Αιτήματα μεγαλύτερα από 64 KB απορρίπτονται με HTTP 413. Όταν η πιστοποίηση είναι ενεργοποιημένη, η πρόσβαση στις μεθόδους ελέγχεται από ρόλο JWT. Δείτε Πιστοποίηση & Ρόλοι για τον πλήρη πίνακα μεθόδων.

Auth Service

Το Auth Service είναι ένα προαιρετικό συστατικό που εκδίδει JWT HS256 (λήξη σε 24 ώρες) για έλεγχο πρόσβασης στο gateway. Ενεργοποιείται όταν ορίζεται η μεταβλητή περιβάλλοντος JWT_SECRET. Χωρίς αυτήν, το gateway αποδέχεται όλες τις συνδέσεις.

Claims JWT: sub (UUID χρήστη), role ("user" ή "operator"), iss ("private-channel-auth"), aud ("private-channel-gateway"), exp (Unix timestamp). Τα iss και aud επαληθεύονται από τη διαμόρφωση JWT του gateway, όχι από αποσειριοποίηση στη δομή claims της εφαρμογής: μόνο τα sub, role και exp είναι διαθέσιμα στον κώδικα επιπέδου εφαρμογής.

Ρόλοι:

  • user - πρόσβαση περιορισμένη στα επαληθευμένα πορτοφόλια του ιδίου· δεν μπορεί να καλέσει getBlock, getTransaction ή simulateTransaction
  • operator - παρακάμπτει όλους τους ελέγχους ιδιοκτησίας· πλήρης πρόσβαση σε μεθόδους RPC· πρέπει να έχει εκδοθεί στη βάση δεδομένων (δεν υπάρχει αυτοεξυπηρετούμενη κλιμάκωση)

Streamer

Ο Streamer είναι ένας διακομιστής WebSocket που ωθεί ενημερώσεις κατάστασης καναλιού στους συνδεδεμένους πελάτες σε πραγματικό χρόνο, εξαλείφοντας την ανάγκη για polling στο RPC. Κάνει polling στη PostgreSQL για αλλαγές κατάστασης. Αποτελεί μέρος του βασικού Docker Compose stack, όχι του devnet stack που αναπτύσσει αυτός ο οδηγός· δείτε την αναφορά Διαμόρφωσης.

  • Θύρα: 8902, διαμορφώσιμη μέσω STREAMER_PORT
  • Σύνδεση: ws://localhost:8902
  • Health endpoint: GET /health - επιστρέφει 503 αν οποιοσδήποτε εσωτερικός βρόχος polling σταματήσει για περισσότερο από 30 δευτερόλεπτα

Το σχήμα συμβάντων WebSocket δεν είναι ακόμα δημόσια τεκμηριωμένο. Ανατρέξτε στο core/src/bin/streamer.rs για λεπτομέρειες υλοποίησης έως ότου είναι διαθέσιμη επίσημη τεκμηρίωση.

Αγωγός Συναλλαγών

Transaction -> [1:Dedup] -> [2:SigVerify] -> [3:Sequencer] -> [4:Executor] -> [5:Settler] -> Database

Οι συναλλαγές που υποβάλλονται στο Gateway διέρχονται από αγωγό πέντε σταδίων πριν δεσμευτεί η κατάστασή τους:

  1. Dedup - φιλτράρει διπλότυπες συναλλαγές πριν εισέλθουν στον αγωγό
  2. SigVerify - επαληθεύει τις υπογραφές συναλλαγών έναντι του δημόσιου κλειδιού του υπογράφοντα
  3. Sequencer - διατάσσει τις έγκυρες συναλλαγές ντετερμινιστικά για τη δημιουργία κανονικού ιστορικού
  4. Executor - εκτελεί συναλλαγές στο επίπεδο λογαριασμών του καναλιού (BOB Cache + AccountsDB), ενημερώνοντας υπόλοιπα off-chain
  5. Settler - δεσμεύει τα συσσωρευμένα αποτελέσματα συναλλαγών στη PostgreSQL και ενημερώνει την κρυφή μνήμη Redis· παράγει νέα blockhashes για τον επόμενο κύκλο block. Ο διακανονισμός στο Mainnet (κλήση ReleaseFunds) διαχειρίζεται ξεχωριστά από την υπηρεσία operator-private-channel

Βασικά Χαρακτηριστικά

Απόρρητο

Οι μεταφορές μεταξύ συμμετεχόντων στο κανάλι δεν καταγράφονται στο Solana Mainnet. Μόνο οι καταθέσεις (είσοδος στο κανάλι) και οι τελικές αναλήψεις (έξοδος από το κανάλι) εμφανίζονται on-chain. Οι ταυτότητες αντισυμβαλλομένων και τα ποσά μεταφοράς δεν είναι ορατά σε εξωτερικούς παρατηρητές κατά τη λειτουργία του καναλιού.

Απόδοση

Ο off-chain αγωγός απομακρύνει τον χρόνο block της Solana από το κρίσιμο μονοπάτι. Οι μεταφορές επιβεβαιώνονται όταν τις επεξεργάζεται ο sequencer, όχι όταν επιβεβαιωθεί ένα block Solana. Αυτό επιτρέπει οριστικότητα σε χρόνο κάτω του δευτερολέπτου και απόδοση που υπερβαίνει το εγγενές TPS της Solana για μεταφορές επιπέδου εφαρμογής.

Διακανονισμός

Κάθε ανάληψη προστατεύεται από on-chain απόδειξη Sparse Merkle Tree. Η ρίζα SMT αποθηκεύεται στο Instance.withdrawal_transactions_root στο Πρόγραμμα Escrow. Όταν καλείται το ReleaseFunds, το πρόγραμμα επαληθεύει πρώτα μια απόδειξη αποκλεισμού για ένα μη ορατό nonce έναντι της τρέχουσας on-chain ρίζας, στη συνέχεια επαληθεύει μια ξεχωριστή απόδειξη συμπερίληψης για αυτό το nonce έναντι της νέας ρίζας που παρέχει ο καλών. Μόνο αφού περάσουν και οι δύο έλεγχοι αποθηκεύει τη νέα ρίζα, καθιστώντας αδύνατη τη διπλή δαπάνη ακόμα και αν ένα κλειδί χειριστή παραβιαστεί.

Μοντέλο Ασφαλείας

Κλειδί διαχειριστή - ελέγχει τη δημιουργία υπηρεσιών (CreateInstance) και την έκδοση χειριστών (AddOperator / RemoveOperator). Η παραβίαση του κλειδιού διαχειριστή επιτρέπει αυθαίρετη έκδοση χειριστών. Το SetNewAdmin μεταφέρει την εξουσία διαχειριστή μη αναστρέψιμα σε ένα μόνο βήμα· προστατέψτε ανάλογα το κλειδί διαχειριστή.

Κλειδιά χειριστών - μπορούν να καλέσουν ReleaseFunds και ResetSmtRoot. Δεν μπορούν να αποδεσμεύσουν κεφάλαια χωρίς έγκυρη απόδειξη αποκλεισμού SMT έναντι της τρέχουσας on-chain ρίζας. Ο on-chain έλεγχος verify_smt_exclusion_proof είναι η τελευταία γραμμή άμυνας έναντι μη εξουσιοδοτημένων αναλήψεων: ένα παραβιασμένο κλειδί χειριστή μόνο του δεν επαρκεί για να αδειάσει το escrow.

Ρίζα SMT - αποθηκεύεται on-chain στο Instance.withdrawal_transactions_root. Ενημερώνεται ατομικά με κάθε κλήση ReleaseFunds. Επειδή κάθε απόδειξη πρέπει να αναφέρεται σε μη ορατό nonce, η διπλή δαπάνη του ίδιου υπολοίπου καναλιού είναι αδύνατη ακόμα και αν ένα κλειδί χειριστή παραβιαστεί.

Εναλλαγή δέντρου - Το Instance.current_tree_index παρακολουθεί τα epoch του δέντρου. Όταν καλείται το ResetSmtRoot, αυξάνει τον δείκτη δέντρου και ακυρώνει όλα τα nonces από το προηγούμενο epoch του δέντρου, παρέχοντας καθαρή αφετηρία για νέους κύκλους διακανονισμού.

Ασφάλεια Λειτουργικών Κλειδιών

Οι off-chain υπηρεσίες χρησιμοποιούν το δικό τους λεξιλόγιο υπογραφόντων, το οποίο δεν σχετίζεται με τις on-chain αρχές admin/operator που περιγράφονται στο Μοντέλο Ασφαλείας παραπάνω. Το ADMIN_PRIVATE_KEY απαιτείται για κάθε υπηρεσία χειριστή και πληρώνει τέλη συναλλαγών· ένα ξεχωριστό, προαιρετικό OPERATOR_PRIVATE_KEY παρέχει την on-chain υπογραφή Operator για ReleaseFunds και ResetSmtRoot, και χρησιμοποιεί ως εναλλακτική την τιμή του ADMIN_PRIVATE_KEY όταν δεν έχει οριστεί. Μην τοποθετείτε ποτέ το κλειδί διαχειριστή υπηρεσίας σε επίπεδο πρωτοκόλλου (που χρησιμοποιείται για CreateInstance / AddOperator / SetNewAdmin) σε καμία από τις δύο μεταβλητές ούτε να το εκθέτετε κατά την εκτέλεση· κρατήστε αυτό το κλειδί ψυχρό και εκτός σύνδεσης.

Τα ReleaseFunds και ResetSmtRoot απαιτούν δύο on-chain υπογραφές: τον πληρωτή τελών (από ADMIN_PRIVATE_KEY) και την αρχή του Operator PDA (από OPERATOR_PRIVATE_KEY, ή ADMIN_PRIVATE_KEY αν αυτό δεν έχει οριστεί). Το devnet walkthrough αυτού του οδηγού ανάπτυξης τοποθετεί το παραγόμενο operator keypair στο ADMIN_PRIVATE_KEY και αφήνει το OPERATOR_PRIVATE_KEY μη ορισμένο, ώστε το ίδιο keypair να καλύπτει και τους δύο ρόλους υπογράφοντος. Αντιμετωπίστε όποιο κλειδί καταλήξει στο ADMIN_PRIVATE_KEY με τους ίδιους ελέγχους όπως ένα ιδιωτικό κλειδί hot wallet:

  • Αποθηκεύστε το μόνο στο αρχείο .env που εξαιρείται από το git, ποτέ στο .env.devnet ή σε οποιαδήποτε δεσμευμένη διαμόρφωση
  • Για αναπτύξεις παραγωγής, εξετάστε τη χρήση secrets manager (AWS Secrets Manager, HashiCorp Vault) αντί για μεταβλητή περιβάλλοντος σε απλό κείμενο
  • Το keypair διαχειριστή υπηρεσίας σε επίπεδο πρωτοκόλλου (που χρησιμοποιείται για κλήση AddOperator / SetNewAdmin) πρέπει να διατηρείται ψυχρό· απαιτείται μόνο κατά τη ρύθμιση της υπηρεσίας και την έκδοση χειριστών, όχι κατά την εκτέλεση

Το SetNewAdmin μεταφέρει δικαιώματα διαχειριστή μη αναστρέψιμα σε μία μόνο συναλλαγή: ο τρέχων διαχειριστής δεν έχει μονοπάτι ανάκτησης χωρίς τη συνεργασία του νέου διαχειριστή. Μην το καλείτε χωρίς να επαληθεύσετε τη διεύθυνση στόχου.

Επόμενα Βήματα

Is this page helpful?

© 2026 Ίδρυμα Solana. Με επιφύλαξη παντός δικαιώματος.