Emissione di Token con Saldi Riservati su Solana
Questa guida è destinata agli emittenti: team che creano e gestiscono un mint Token-2022 che utilizza i Saldi Riservati. Tratta le decisioni da prendere al momento della creazione del mint e le operazioni da eseguire nel corso della sua vita. Per il flusso lato titolare (deposito, applicazione, trasferimento, prelievo) consulta le pagine passo dopo passo; per il supporto di questi token in un prodotto, consulta la Guida all'Integrazione.
I Saldi Riservati mantengono gli importi dei trasferimenti e i saldi dei conti cifrati, lasciando pubblici gli indirizzi dei conti, il mint e i proprietari. L'estensione si basa sul Programma ZK ElGamal Proof per la verifica delle prove on-chain, quindi il mint è utilizzabile sui cluster in cui tale programma è abilitato.
Decisioni che prendi al momento della creazione
L'estensione Saldi Riservati deve essere inizializzata prima del mint e non può essere aggiunta in seguito. Al momento della creazione è necessario decidere:
- Politica di approvazione: se i conti possono aderire ai Saldi Riservati
senza autorizzazione (
auto) oppure devono essere approvati dall'autorità Saldi Riservati del mint (manual). - Revisore: se impostare una chiave pubblica ElGamal globale per il revisore, in modo che una parte designata possa decifrare ogni importo di trasferimento per il mint. Opzionale e modificabile in seguito.
- Estensioni companion opzionali: commissioni di trasferimento riservato (abbinate all'estensione per le commissioni di trasferimento) e mint/burn riservato, entrambi descritti di seguito. Anche queste devono essere inizializzate al momento della creazione.
Creare un mint riservato
La CLI imposta la politica di approvazione con --enable-confidential-transfers auto o
manual; auto consente a qualsiasi titolare di configurare il proprio conto, mentre manual
condiziona tale operazione all'approvazione da parte dell'autorità Saldi Riservati (che
corrisponde per impostazione predefinita all'autorità del mint). I percorsi client accettano le stesse impostazioni tramite
i parametri ConfidentialTransferMint: un'autorità, il flag di approvazione automatica
e una chiave revisore opzionale. Sia la politica di approvazione che il revisore possono essere
modificati in seguito (vedi Configurare un revisore); solo la
presenza dell'estensione stessa è fissa al momento della creazione.
$ spl-token --program-id TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb create-token --enable-confidential-transfers auto
Configurare un revisore
Un revisore globale è una chiave pubblica ElGamal memorizzata nel mint. Quando impostata, ogni trasferimento riservato cifra ulteriormente il proprio importo con questa chiave, così chiunque detenga la chiave segreta corrispondente può decifrare tutti gli importi dei trasferimenti per il mint. È così che i Saldi Riservati rimangono compatibili con i requisiti di audit e compliance: il pubblico non vede nulla, il revisore vede tutto.
L'autorità Saldi Riservati può impostare, ruotare o rimuovere il revisore in qualsiasi
momento. La stessa operazione aggiorna anche la politica di approvazione. Tramite CLI, la chiave
revisore è una codifica base64 di una chiave pubblica ElGamal; passa --auditor-pubkey none
per rimuoverla e --approve-policy auto|manual per modificare la politica.
La rotazione influisce solo sui trasferimenti futuri. Gli importi nelle transazioni già presenti sulla blockchain rimangono cifrati con la chiave del revisore attiva al momento dell'esecuzione, quindi conserva le vecchie chiavi del revisore se hai bisogno di decifrare l'attività storica.
$ spl-token update-confidential-transfer-settings <MINT_PUBKEY> --auditor-pubkey <AUDITOR_ELGAMAL_PUBKEY>
La chiave segreta del revisore può decifrare ogni importo di trasferimento per
il mint. Custodiscila con la stessa attenzione riservata a una chiave di firma
e pianifica la rotazione. Impostare il revisore su None disabilita la
visibilità degli importi per tutti, ad eccezione dei titolari dei conti
stessi.
Approvazione degli account (politica manuale)
Con una politica di approvazione manuale, un conto configurato per i Saldi Riservati non può effettuare transazioni in modo riservato finché l'autorità Saldi Riservati non lo approva. Questo offre agli emittenti un controllo per i partecipanti in allowlist o con KYC. La CLI non espone un comando di approvazione, quindi l'approvazione viene eseguita tramite client.
token.confidential_transfer_approve_account(&token_account,&authority,&[&authority_keypair],).await?;
Commissioni di trasferimento riservato
Se il tuo mint applica una commissione di trasferimento e
i trasferimenti sono riservati, anche la commissione deve essere trattenuta in modo riservato. L'estensione
ConfidentialTransferFeeConfig gestisce questo aspetto e viene inizializzata al momento della
creazione del mint insieme alle estensioni per la commissione di trasferimento e i Saldi Riservati.
Le commissioni trattenute si accumulano cifrate sugli account dei destinatari, vengono raccolte nel mint e poi prelevate dall'autorità di prelievo delle commissioni trattenute. Ogni importo di commissione rimane cifrato per tutta la durata del processo. Nulla di tutto ciò è esposto tramite la CLI. La chiave segreta ElGamal dell'autorità di prelievo delle commissioni trattenute può decifrare gli importi delle commissioni trattenute, che combinati con i parametri pubblici delle commissioni possono rivelare informazioni sugli importi dei trasferimenti: tratta quindi tale chiave come sensibile.
Inizializza la configurazione delle commissioni
Includi questo insieme a ConfidentialTransferMint e alla configurazione delle
commissioni di trasferimento nella stessa creazione del mint.
use spl_token_client::token::ExtensionInitializationParams;ExtensionInitializationParams::ConfidentialTransferFeeConfig {authority: Some(authority.pubkey().into()),withdraw_withheld_authority_elgamal_pubkey: withdraw_withheld_elgamal_pubkey,};
Raccogliere e prelevare le commissioni trattenute
La raccolta sposta le commissioni trattenute cifrate dagli account nel mint; il prelievo le sposta fuori dal mint verso un account scelto. Sono coinvolte due autorità, entrambe possono differire dall'autorità del mint:
- L'autorità delle commissioni di trasferimento riservate (il
authorityimpostato suConfidentialTransferFeeConfig) abilita o disabilita la raccolta. - L'autorità di prelievo delle commissioni trattenute (dall'estensione delle
commissioni di trasferimento,
TransferFeeConfig) preleva le commissioni raccolte dal mint.
I prelievi richiedono una prova di uguaglianza e una prova di intervallo, fornite inline o verificate in account di stato del contesto.
// Permissionless: move withheld fees from accounts into the mint.token.confidential_transfer_harvest_withheld_tokens_to_mint(&[&source_account]).await?;// Withdraw withheld fees from the mint (requires the withdraw withheld authority).token.confidential_transfer_withdraw_withheld_tokens_from_mint(&destination_account,&withdraw_withheld_authority,None, // proof context state account, supplied inline if NoneNone, // withheld tokens info, fetched if None&withdraw_withheld_elgamal_keypair,&destination_elgamal_pubkey,&new_decryptable_available_balance,&[&withdraw_withheld_authority_keypair],).await?;
Nel client JS, il prelievo delle commissioni raccolte dal mint
(getWithdrawWithheldTokensFromMintForConfidentialTransferFeeInstruction)
richiede inoltre una prova di uguaglianza e una prova di intervallo verificate
in account di stato del contesto, quindi segue lo stesso schema con account di
prova di un trasferimento riservato.
Mint e burn riservati
L'estensione ConfidentialMintBurn consente all'autorità del mint di emettere e
bruciare supply direttamente a fronte di saldi riservati, mantenendo la supply
totale cifrata. Un mint con questa estensione disabilita il percorso pubblico di
deposito e prelievo, poiché i token esistono esclusivamente in forma riservata.
Consulta la
documentazione del protocollo
per il modello completo.
Il mint/burn riservato è più semplice tramite il spl-token-client Rust, che
genera le prove richieste e sequenza le transazioni per te. Il client JS
@solana-program/token-2022 include i costruttori di istruzioni di basso
livello (getConfidentialMintInstruction, getConfidentialBurnInstruction e
simili), ma nessun helper di alto livello per la generazione delle prove e
nessun comando CLI, quindi gli esempi seguenti sono solo in Rust.
Inizializza l'estensione alla creazione del mint, quindi esegui mint, burn e riconcilia la fornitura nel tempo. Il minting emette un importo cifrato nel saldo confidenziale di un destinatario; il burning rimuove un importo cifrato in un burn in sospeso che viene successivamente incorporato nella fornitura. Entrambi generano prove come un trasferimento confidenziale.
use spl_token_client::token::ExtensionInitializationParams;// 1. Initialize at creation (alongside ConfidentialTransferMint).ExtensionInitializationParams::ConfidentialMintBurn {supply_elgamal_pubkey, // encrypts the confidential supplydecryptable_supply, // AES ciphertext of the initial supply (zero)};// 2. Mint an encrypted amount into a recipient's confidential balance.token.confidential_transfer_mint(&mint_authority,&destination_account,None, // equality proof accountNone, // ciphertext validity proof accountNone, // range proof accountmint_amount,&supply_elgamal_keypair,&destination_elgamal_pubkey,auditor_elgamal_pubkey, // Option&supply_aes_key,None, // supply account info, fetched if None&[&mint_authority_keypair],).await?;// 3. Burn an encrypted amount from a holder's confidential balance into the// mint's pending burn. Generates proofs like a confidential transfer.token.confidential_transfer_burn(&owner,&source_account,None, // equality proof accountNone, // ciphertext validity proof accountNone, // range proof accountburn_amount,&source_elgamal_keypair,&supply_elgamal_pubkey,auditor_elgamal_pubkey, // Option&source_aes_key,None, // burn account info, fetched if None&[&owner_keypair],).await?;// 4. Fold the accumulated pending burn into the confidential supply.token.confidential_transfer_apply_pending_burn(&mint_authority, &[&mint_authority_keypair]).await?;
Ruota la chiave di cifratura della fornitura con
confidential_transfer_rotate_supply_elgamal_pubkey (il burn in sospeso deve
essere prima zero), e aggiorna il testo cifrato della fornitura leggibile con
confidential_transfer_update_decrypt_supply.
Considerazioni operative e di conformità
- Custodia della chiave dell'auditor. Se imposti un auditor, la chiave segreta dell'auditor è una chiave di decifratura di alto valore. Conservala e ruotala con attenzione, e decidi chi all'interno della tua organizzazione (o quale autorità di regolamentazione) la detiene.
- Postura di conformità. Lo screening degli indirizzi e l'analisi del grafo delle controparti continuano a funzionare perché gli indirizzi rimangono pubblici. Il monitoraggio basato sugli importi dipende dalla chiave dell'auditor o dalla divulgazione selettiva da parte dei titolari dei conti. Definisci il tuo approccio prima del lancio.
- Onboarding dei titolari. La configurazione di un conto confidenziale richiede la firma del proprietario. Per abilitare i conti degli utenti in modo fluido, fai loro registrare una chiave ElGamal una volta sola e utilizza il percorso del registro, descritto nella Guida all'integrazione.
- Numero di transazioni. Un trasferimento confidenziale attualmente comprende alcune transazioni dipendenti perché le prove superano il limite di dimensione delle transazioni attuale. Il formato di transazione v1 (in arrivo con Agave v4.2) innalza tale limite e si prevede che consentirà una singola transazione on-chain.
Is this page helpful?