Overzicht

Private Channels is niet beveiligingsgecontroleerd en wordt niet aanbevolen voor productiegebruik met echte fondsen zonder een grondig beveiligingsonderzoek.

Een instantie uitrollen? Ga naar de Operatorsgids. Integreren tegen een bestaande instantie? Ga naar de Quickstart. Deze pagina is de architectuurreferentie voor beide doelgroepen.

Architectuur

Private Channels bestaat uit vier componenten: twee on-chain Solana-programma's (Escrow en Withdraw) en twee off-chain services (Gateway en Auth Service). Samen vormen ze een state channel-protocol waarbij fondsen op Mainnet staan maar overdrachten off-chain worden afgehandeld.

Escrow-programma

Het Escrow-programma is een on-chain Solana-programma dat gestorte SPL-tokens beheerd. Het is het vertrouwensanker van het systeem: alle fondsen staan uiteindelijk in escrow totdat een operator een geldig Sparse Merkle Tree-uitsluitingsbewijs levert om ze vrij te geven.

  • Programma-ID: 9tgHa1DcnaSSUtmMsst8ovKTe1Gfxzezn27KnH9xXYeU
  • Dit ID is gecompileerd in het programma-binaire bestand via declare_id!(). Off-chain services lezen hetzelfde ID tijdens het compileren uit het gegenereerde client-crate, niet uit een omgevingsvariabele.
  • Beheert Instance-, AllowedMint- en Operator-PDA's
  • Instructies: CreateInstance, AllowMint, BlockMint, AddOperator, RemoveOperator, SetNewAdmin, Deposit, ReleaseFunds, ResetSmtRoot

Withdraw-programma

Het Withdraw-programma draait op het private channel-netwerk, niet op Solana Mainnet. Gebruikers roepen WithdrawFunds aan om hun token-saldo aan de kanaalzijde te verbranden. Deze verbranding geeft fondsen niet automatisch vrij; het signaleert aan de operator dat een opname in behandeling is. De operator roept vervolgens ReleaseFunds aan op het Escrow- programma met een geldig SMT-bewijs om de afwikkeling te voltooien.

  • Programma-ID: J231K9UEpS4y4KAPwGc4gsMNCjKFRMYcQBcjVW7vBhVi
  • Dit ID is gecompileerd in het programma-binaire bestand. Off-chain services lezen hetzelfde ID tijdens het compileren uit het gegenereerde client-crate, niet uit een omgevingsvariabele.

Gateway

De Gateway is een Solana JSON-RPC-compatibele proxy die clientverzoeken routeert naar het schrijfknooppunt van het channel-netwerk (voor het indienen van transacties) en het leesknooppunt (voor query's). De configuratie verloopt via omgevingsvariabelen: GATEWAY_PORT, GATEWAY_WRITE_URL, GATEWAY_READ_URL.

Health-eindpunten (geen authenticatie vereist):

  • GET /health - liveness-check; retourneert 200 {"status":"ok"}
  • GET /ready - diepe gereedheidscontrole, controleert schrijf- + leesknooppunten; retourneert 200 {"status":"ready"} of 503 {"status":"degraded"}

RPC-methoderouting en -toegang

De gateway stuurt sendTransaction naar het schrijfknooppunt en alle andere methoden naar het leesknooppunt. Verzoeken groter dan 64 KB worden geweigerd met HTTP 413. Wanneer authenticatie is ingeschakeld, wordt methodetoegang bewaakt door JWT-rol. Zie Authenticatie & Rollen voor de volledigematrixoverzicht van methoden.

Auth Service

De Auth Service is een optioneel onderdeel dat HS256-JWT's uitgeeft (24 uur geldig) voor toegangscontrole op de gateway. Het wordt ingeschakeld wanneer de omgevingsvariabele JWT_SECRET is ingesteld. Zonder deze instelling accepteert de gateway alle verbindingen.

JWT-claims: sub (gebruiker-UUID), role ("user" of "operator"), iss ("private-channel-auth"), aud ("private-channel-gateway"), exp (Unix- tijdstempel). iss en aud worden gevalideerd door de JWT-configuratie van de gateway, niet gedeserialiseerd in de applicatieclaims-struct: alleen sub, role en exp zijn beschikbaar voor code op de applicatielaag.

Rollen:

  • user - toegang beperkt tot eigen geverifieerde wallets; kan getBlock, getTransaction of simulateTransaction niet aanroepen
  • operator - omzeilt alle eigendomscontroles; volledige RPC-methodetoegang; moet worden ingericht in de database (geen zelfbedieningsescalatie)

Streamer

De Streamer is een WebSocket-server die channel-statusupdates in real-time naar verbonden clients pusht, waardoor polling van de RPC niet nodig is. Hij pollt PostgreSQL op statuswijzigingen. Het maakt deel uit van de basis Docker Compose-stack, niet van de devnet-stack die deze gids uitrolt; zie de Configuratiereferentie.

  • Poort: 8902, configureerbaar via STREAMER_PORT
  • Verbinden: ws://localhost:8902
  • Health-eindpunt: GET /health - retourneert 503 als een interne poll-loop langer dan 30 seconden vastloopt

Het WebSocket-gebeurtenisschema is nog niet openbaar gedocumenteerd. Raadpleeg core/src/bin/streamer.rs voor implementatiedetails totdat formele documentatie beschikbaar is.

Transactiepijplijn

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

Transacties die bij de Gateway worden ingediend, doorlopen een vijfstappenpijplijn voordat hun toestand wordt vastgelegd:

  1. Dedup - filtert dubbele transacties voordat ze de pijplijn binnenkomen
  2. SigVerify - valideert transactiehandtekeningen tegen de openbare sleutel van de ondertekenaar
  3. Sequencer - ordent geldige transacties deterministisch om een canonieke geschiedenis te bepalen
  4. Executor - voert transacties uit tegen de accountslaag van het kanaal (BOB Cache + AccountsDB) en werkt saldi off-chain bij
  5. Settler - legt geaccumuleerde transactieresultaten vast in PostgreSQL en werkt de Redis-cache bij; genereert nieuwe blockhashes voor de volgende blokronde. Mainnet-afwikkeling (het aanroepen van ReleaseFunds) wordt afzonderlijk afgehandeld door de operator-private-channel-service

Belangrijkste functies

Privacy

Overdrachten tussen channel-deelnemers worden niet vastgelegd op Solana Mainnet. Alleen stortingen (het kanaal binnengaan) en definitieve opnames (het kanaal verlaten) verschijnen on-chain. Tegenpartijidentiteiten en overdrachtsbedragen zijn niet zichtbaar voor buitenstaanders tijdens de werking van het kanaal.

Prestaties

De off-chain pijplijn verwijdert de bloktijd van Solana uit het kritieke pad. Overdrachten worden bevestigd wanneer de sequencer ze verwerkt, niet wanneer een Solana-blok wordt bevestigd. Dit maakt sub-seconde finaliteit en doorvoer mogelijk die de native TPS van Solana voor overdrachten op de applicatielaag overstijgt.

Afwikkeling

Elke opname wordt beschermd door een on-chain Sparse Merkle Tree-bewijs. De SMT- wortel wordt opgeslagen in Instance.withdrawal_transactions_root op het Escrow-programma. Wanneer ReleaseFunds wordt aangeroepen, verifieert het programma eerst een uitsluitingsbewijs voor een ongeziene nonce tegen de huidige on-chain wortel, en verifieert vervolgens een apart inclusionsbewijs voor die nonce tegen de door de aanroeper geleverde nieuwe wortel. Pas nadat beiden controles zijn geslaagd, slaat het de nieuwe wortel op, waardoor dubbel besteden onmogelijk is, zelfs als een operatorsleutel is gecompromitteerd.

Beveiligingsmodel

Adminsleutel - beheert het aanmaken van instanties (CreateInstance) en het inrichten van operators (AddOperator / RemoveOperator). Compromittering van de adminsleutel maakt willekeurige operatorinrichting mogelijk. SetNewAdmin draagt adminbevoegdheid onomkeerbaar over in één stap; bescherm de adminsleutel dienovereenkomstig.

Operatorsleutels - kunnen ReleaseFunds en ResetSmtRoot aanroepen. Ze kunnen geen fondsen vrijgeven zonder een geldig SMT-uitsluitingsbewijs tegen de huidige on-chain wortel. De on-chain verify_smt_exclusion_proof-controle is de laatste verdedigingslinie tegen ongeoorloofde opnames: een gecompromitteerde operatorsleutel alleen is niet voldoende om de escrow leeg te halen.

SMT-wortel - on-chain opgeslagen in Instance.withdrawal_transactions_root. Atomair bijgewerkt bij elke ReleaseFunds-aanroep. Omdat elk bewijs moet verwijzen naar een ongeziene nonce, is dubbel besteden van hetzelfde channel-saldo onmogelijk, zelfs als een operatorsleutel is gecompromitteerd.

Boomrotatie - Instance.current_tree_index houdt boom-epochs bij. Wanneer ResetSmtRoot wordt aangeroepen, verhoogt het de boomindex en maakt alle nonces van de vorige boom-epoch ongeldig, wat een schone lei biedt voor nieuwe afwikkelingscycli.

Operationele sleutelbeveiliging

De off-chain services gebruiken hun eigen ondertekenaarsvocabulaire, dat losstaat van de on-chain admin/operator-bevoegdheden zoals beschreven in het Beveiligingsmodel hierboven. ADMIN_PRIVATE_KEY is vereist voor elke operatorservice en betaalt transactiekosten; een afzonderlijke, optionele OPERATOR_PRIVATE_KEY levert de on-chain Operator-handtekening voor ReleaseFunds en ResetSmtRoot, en valt terug op de waarde van ADMIN_PRIVATE_KEY wanneer niet ingesteld. Zet de admin-sleutel van het protocol-niveau (gebruikt voor CreateInstance / AddOperator / SetNewAdmin) nooit in een van beide variabelen en stel deze niet bloot tijdens uitvoering; bewaar die sleutel koud en offline.

ReleaseFunds en ResetSmtRoot vereisen twee on-chain handtekeningen: de fee payer (van ADMIN_PRIVATE_KEY) en de bevoegdheid van de Operator PDA (van OPERATOR_PRIVATE_KEY, of ADMIN_PRIVATE_KEY als dat niet is ingesteld). De devnet-walkthrough van deze implementatiegids plaatst het gegenereerde operator keypair in ADMIN_PRIVATE_KEY en laat OPERATOR_PRIVATE_KEY leeg, zodat hetzelfde keypair beide ondertekenaarsrollen vervult. Behandel de sleutel die in ADMIN_PRIVATE_KEY terechtkomt met dezelfde controles als een privésleutel van een hot wallet:

  • Sla het alleen op in het gitignored .env-bestand, nooit in .env.devnet of een vastgelegde configuratie
  • Overweeg voor productie-uitrol een secrets manager (AWS Secrets Manager, HashiCorp Vault) in plaats van een plaintext-omgevingsvariabele
  • Het keypair van de admin op protocolniveau (gebruikt om AddOperator / SetNewAdmin aan te roepen) moet koud worden bewaard; het is alleen nodig tijdens de installatie van de instantie en het inrichten van operators, niet tijdens de uitvoering

SetNewAdmin draagt beheerdersrechten over onomkeerbaar in één enkele transactie: de huidige beheerder heeft geen herstelpad zonder de medewerking van de nieuwe beheerder. Roep het niet aan zonder het doeladres te verifiëren.

Volgende stappen

Is this page helpful?

Inhoudsopgave

Pagina Bewerken
© 2026 Solana Foundation. Alle rechten voorbehouden.