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.

Decisioni che prendi al momento della creazione

L'estensione Confidential Transfer deve essere inizializzata prima che il mint venga inizializzato e non può essere aggiunta in seguito. Al momento della creazione decidi:

  • Politica di approvazione: se gli account possono aderire ai trasferimenti riservati senza permesso (auto) o 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. 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 account, mentre manual condiziona tale operazione all'approvazione dell'autorità di trasferimento riservato (che predefinita è l'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 inoltre il proprio importo con questa chiave, così chiunque detenga la chiave segreta corrispondente può decifrare tutti gli importi di trasferimento per il mint. È così che i trasferimenti riservati rimangono compatibili con i requisiti di audit e conformità: il pubblico non vede nulla, il revisore vede tutto.

L'autorità di trasferimento riservato può impostare, ruotare o rimuovere il revisore in qualsiasi momento. La stessa operazione aggiorna anche la politica di approvazione. Nella CLI, la chiave del 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 account configurato per i trasferimenti riservati non può effettuare transazioni in modo riservato finché l'autorità di trasferimento riservato non lo approva. Questo offre agli emittenti un controllo per i partecipanti inclusi nella allowlist o sottoposti a KYC. La CLI non espone un comando di approvazione, quindi l'approvazione viene eseguita tramite un 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 questa funzionalità e viene inizializzata durante la creazione del mint insieme alle estensioni per la commissione di trasferimento e il trasferimento riservato.

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 authority impostato su ConfidentialTransferFeeConfig) 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 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 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.

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 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?

© 2026 Solana Foundation. Tutti i diritti riservati.