Guida all'Emissione di Confidential Transfer

Emissione di Token con Confidential Transfer su Solana

Questa guida è rivolta agli emittenti: team che creano e gestiscono un mint Token-2022 che utilizza l'estensione Confidential Transfer. Tratta le decisioni da prendere al momento della creazione del mint e le operazioni da eseguire durante il ciclo di vita del mint. Per il flusso lato titolare (deposito, applicazione, trasferimento, prelievo) consulta le pagine passo-passo, e per supportare questi token in un prodotto consulta la Guida all'Integrazione.

I trasferimenti riservati mantengono gli importi dei trasferimenti e i saldi dei conti cifrati, lasciando pubblici gli indirizzi dei conti, il mint e i proprietari. Si basano sul ZK ElGamal Proof Program per la verifica delle prove on-chain, quindi il mint è utilizzabile su cluster in cui tale programma è abilitato.

Disponibilità

I trasferimenti riservati richiedono il Token-2022 program@v11.0.0 o versione successiva. Sono disponibili oggi su devnet e sono previsti per essere abilitati su mainnet a giugno 2026. Il Token Extension Program è distribuito separatamente su ogni cluster, quindi verificare il deployment sul cluster di destinazione.

Decisioni da prendere al momento della creazione

L'estensione Confidential Transfer deve essere inizializzata prima del mint e non può essere aggiunta in seguito. Al momento della creazione si decide:

  • Criteri di approvazione: se i conti possono aderire ai trasferimenti riservati senza autorizzazione (auto) oppure devono essere approvati dall'autorità di trasferimento riservato 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. Facoltativo e modificabile in seguito.
  • Estensioni companion opzionali: commissioni di trasferimento riservate (abbinate all'estensione per le commissioni di trasferimento) e mint/burn riservati, entrambi trattati 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 account, mentre manual condiziona tale operazione all'approvazione dell'autorità di trasferimento riservato (che predefinitamente corrisponde all'autorità del mint). I percorsi client ricevono le stesse impostazioni tramite i parametri ConfidentialTransferMint: un'autorità, il flag di approvazione automatica e una chiave opzionale per l'auditor. Sia la politica di approvazione che l'auditor possono essere modificati in seguito (vedere Configurare un auditor); solo la presenza dell'estensione stessa è fissa al momento della creazione.

$ spl-token --program-id TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb create-token --enable-confidential-transfers auto

Configurare un auditor

Un auditor globale è una chiave pubblica ElGamal memorizzata sul mint. Quando impostato, ogni trasferimento riservato cifra inoltre il proprio importo con questa chiave, in modo che chiunque possieda la corrispondente chiave segreta possa decifrare tutti gli importi dei trasferimenti per il mint. È così che i trasferimenti riservati restano compatibili con i requisiti di audit e conformità: il pubblico non vede nulla, l'auditor vede tutto.

L'autorità di trasferimento riservato può impostare, ruotare o rimuovere l'auditor in qualsiasi momento. La stessa operazione aggiorna anche la politica di approvazione. Nella CLI, la chiave dell'auditor è una codifica base64 di una chiave pubblica ElGamal; passare --auditor-pubkey none per rimuoverla e --approve-policy auto|manual per modificare la politica.

La rotazione interessa solo i trasferimenti futuri. Gli importi nelle transazioni già presenti on-chain rimangono cifrati con la chiave dell'auditor attiva al momento della loro esecuzione, pertanto conservare le vecchie chiavi dell'auditor se si ha necessità di decifrare l'attività storica.

$ spl-token update-confidential-transfer-settings <MINT_PUBKEY> --auditor-pubkey <AUDITOR_ELGAMAL_PUBKEY>

La chiave segreta dell'auditor può decifrare ogni importo di trasferimento per il mint. Custodirla con la stessa rigore di una chiave di firma e pianificarne la rotazione. Impostare l'auditor su None disabilita la visibilità degli importi per tutti ad eccezione dei titolari degli account stessi.

Approvazione degli account (policy manuale)

Con una policy di approvazione manuale, un account configurato per i trasferimenti riservati non può effettuare transazioni in modo riservato finché l'autorità per i trasferimenti riservati non lo approva. Questo fornisce agli emittenti un controllo per i partecipanti in allowlist o sottoposti a KYC. La CLI non espone un comando di approvazione, quindi l'approvazione viene effettuata tramite un client.

token
.confidential_transfer_approve_account(
&token_account,
&authority,
&[&authority_keypair],
)
.await?;

Commissioni sui trasferimenti riservati

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 alla creazione del mint insieme alle estensioni per la commissione di trasferimento e per i trasferimenti riservati.

Le commissioni trattenute si accumulano in forma cifrata sugli account dei destinatari, vengono raccolte nel mint e poi prelevate dall'autorità di prelievo delle commissioni trattenute. Ogni importo delle commissioni rimane cifrato per tutto il processo. Nulla di 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 quella chiave come sensibile.

Inizializzare la configurazione delle commissioni

Includi questo insieme a ConfidentialTransferMint e alla configurazione della commissione 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 dal mint a un account scelto. Sono coinvolte due autorità, entrambe potenzialmente diverse dall'autorità del mint:

  • L'autorità per le commissioni sui trasferimenti riservati (il authority impostato su ConfidentialTransferFeeConfig) abilita o disabilita la raccolta.
  • L'autorità di prelievo delle commissioni trattenute (dall'estensione della commissione 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 negli 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 None
None, // 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 negli account di stato del contesto, pertanto segue lo stesso schema degli account di prova di un trasferimento riservato.

Mint e burn riservati

L'estensione ConfidentialMintBurn consente all'autorità di mint di emettere e bruciare la fornitura direttamente sui saldi riservati, mantenendo la fornitura 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 necessarie e sequenzia le transazioni automaticamente. Il client JS @solana-program/token-2022 include i costruttori di istruzioni a basso livello (getConfidentialMintInstruction, getConfidentialBurnInstruction e simili), ma nessun helper di alto livello per la generazione delle prove, e non sono disponibili comandi 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 mint emette un importo cifrato nel saldo riservato di un destinatario; il burn rimuove un importo cifrato in un burn in sospeso che viene successivamente incorporato nella fornitura. Entrambi generano prove come un trasferimento riservato.

confidential-mint-burn.rs
use spl_token_client::token::ExtensionInitializationParams;
// 1. Initialize at creation (alongside ConfidentialTransferMint).
ExtensionInitializationParams::ConfidentialMintBurn {
supply_elgamal_pubkey, // encrypts the confidential supply
decryptable_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 account
None, // ciphertext validity proof account
None, // range proof account
mint_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 account
None, // ciphertext validity proof account
None, // range proof account
burn_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 azzerato) e aggiorna il testo cifrato della fornitura leggibile con confidential_transfer_update_decrypt_supply.

Considerazioni operative e di conformità

  • Custodia della chiave auditor. Se imposti un auditor, la chiave segreta dell'auditor è una chiave di decifratura di alto valore. Conservala e ruotala con cura, e stabilisci 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 poiché gli indirizzi rimangono pubblici. Il monitoraggio basato sugli importi dipende dalla chiave auditor o dalla divulgazione selettiva da parte dei titolari degli account. Definisci il tuo approccio prima del lancio.
  • Onboarding dei titolari. La configurazione di un account riservato richiede la firma del proprietario. Per predisporre gli account degli utenti in modo fluido, fai sì che registrino una chiave ElGamal una sola volta e utilizza il percorso del registro, descritto nella Guida all'integrazione.
  • Numero di transazioni. Un trasferimento riservato comprende attualmente alcune transazioni dipendenti poiché le prove superano il limite attuale di dimensione delle transazioni. Il formato di transazione v1 (disponibile con Agave v4.2) aumenta tale limite e si prevede che consenta una singola transazione onchain.

Is this page helpful?

© 2026 Solana Foundation. Tutti i diritti riservati.