Emisión de Tokens de Transferencia Confidencial en Solana
Esta guía está dirigida a emisores: equipos que crean y operan un mint de Token-2022 que utiliza la extensión de Transferencia Confidencial. Cubre las decisiones que tomas en el momento de la creación del mint y las operaciones que realizas durante la vida del mint. Para el flujo del titular (depósito, aplicación, transferencia, retiro), consulta las páginas paso a paso, y para dar soporte a estos tokens en un producto, consulta la Guía de Integración.
Las transferencias confidenciales mantienen los montos de transferencia y los saldos de las cuentas cifrados, mientras que las direcciones de las cuentas, el mint y los propietarios permanecen públicos. Se basan en el Programa de Pruebas ZK ElGamal para la verificación de pruebas en cadena, por lo que el mint es utilizable en clústeres donde ese programa está habilitado.
Decisiones que tomas al crear
La extensión de Transferencia Confidencial debe inicializarse antes de que se inicialice el mint y no puede añadirse posteriormente. Al crearlo, decides:
- Política de aprobación: si las cuentas pueden optar por transferencias
confidenciales sin permisos (
auto) o deben ser aprobadas por la autoridad de transferencia confidencial del mint (manual). - Auditor: si se establece un pubkey ElGamal de auditor global para que una parte designada pueda descifrar todos los importes de transferencia del mint. Opcional, y puede cambiarse más adelante.
- Extensiones complementarias opcionales: comisiones de transferencia confidencial (junto con la extensión de comisión de transferencia) y mint/burn confidencial, ambas descritas a continuación. Estas también deben inicializarse al crear.
Crear un mint confidencial
La CLI establece la política de aprobación con
--enable-confidential-transfers auto o manual; auto permite que cualquier
titular configure su propia cuenta, mientras que manual condicionalo a la
aprobación de la autoridad de transferencia confidencial (que por defecto es la
autoridad del mint). Las rutas del cliente aplican la misma configuración a
través de los parámetros ConfidentialTransferMint: una autoridad, el indicador
de aprobación automática y una clave de auditor opcional. Tanto la política de
aprobación como el auditor pueden cambiarse más adelante (ver
Configurar un auditor); solo la presencia de la propia
extensión queda fijada al crear.
$ spl-token --program-id TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb create-token --enable-confidential-transfers auto
Configurar un auditor
Un auditor global es un pubkey ElGamal almacenado en el mint. Cuando se establece, cada transferencia confidencial cifra adicionalmente su importe con esta clave, de modo que quien posea la clave secreta correspondiente puede descifrar todos los importes de transferencia del mint. Así es como las transferencias confidenciales se mantienen compatibles con los requisitos de auditoría y cumplimiento normativo: el público no ve nada, el auditor lo ve todo.
La autoridad de transferencia confidencial puede establecer, rotar o eliminar el
auditor en cualquier momento. La misma operación también actualiza la política
de aprobación. En la CLI, la clave del auditor es una codificación base64 de una
clave pública ElGamal; pase --auditor-pubkey none para eliminarla e
--approve-policy auto|manual para cambiar la política.
La rotación solo afecta a las transferencias futuras. Los montos en transacciones ya registradas en la cadena permanecen cifrados con la clave de auditor que estaba activa cuando se ejecutaron, por lo que conserve las claves de auditor antiguas si necesita descifrar actividad histórica.
$ spl-token update-confidential-transfer-settings <MINT_PUBKEY> --auditor-pubkey <AUDITOR_ELGAMAL_PUBKEY>
La clave secreta del auditor puede descifrar cada monto de transferencia del
mint. Custódiela con el mismo rigor que una clave de firma y planifique su
rotación. Establecer el auditor en None deshabilita la visibilidad de los
montos para todos excepto para los propios titulares de las cuentas.
Aprobación de cuentas (política manual)
Con una política de aprobación manual, una cuenta configurada para transferencias confidenciales no puede operar de forma confidencial hasta que la autoridad de transferencia confidencial la apruebe. Esto le otorga a los emisores un control de acceso para participantes incluidos en listas de permitidos o verificados mediante KYC. La CLI no expone un comando de aprobación, por lo que la aprobación se realiza a través de un cliente.
token.confidential_transfer_approve_account(&token_account,&authority,&[&authority_keypair],).await?;
Comisiones de transferencia confidencial
Si su mint cobra una
comisión por transferencia y las
transferencias son confidenciales, la comisión también debe retenerse de forma
confidencial. La extensión ConfidentialTransferFeeConfig gestiona esto y se
inicializa en el momento de creación del mint junto con las extensiones de
comisión por transferencia y de transferencia confidencial.
Las comisiones retenidas se acumulan cifradas en las cuentas de los destinatarios, se recolectan en el mint y luego son retiradas por la autoridad de retiro de comisiones. Cada monto de comisión permanece cifrado en todo momento. Nada de esto está expuesto a través de la CLI. La clave secreta ElGamal de la autoridad de retiro de comisiones puede descifrar los montos de comisiones retenidas, lo que, combinado con los parámetros públicos de comisiones, puede revelar información sobre los montos de las transferencias; por lo tanto, trate esa clave como información sensible.
Inicializar la configuración de tarifas
Incluye esto junto con ConfidentialTransferMint y la configuración de tarifas
de transferencia en la misma creación del mint.
use spl_token_client::token::ExtensionInitializationParams;ExtensionInitializationParams::ConfidentialTransferFeeConfig {authority: Some(authority.pubkey().into()),withdraw_withheld_authority_elgamal_pubkey: withdraw_withheld_elgamal_pubkey,};
Recolectar y retirar tarifas retenidas
La recolección mueve las tarifas retenidas cifradas de las cuentas al mint; el retiro las saca del mint hacia una cuenta elegida. Intervienen dos autoridades, y cualquiera de ellas puede diferir de la autoridad del mint:
- La autoridad de tarifas de transferencia confidencial (el
authorityestablecido enConfidentialTransferFeeConfig) habilita o deshabilita la recolección. - La autoridad de retiro de tarifas retenidas (del
TransferFeeConfigde la extensión de tarifas de transferencia) retira las tarifas recolectadas fuera del mint.
Los retiros requieren una prueba de igualdad y una prueba de rango, proporcionadas en línea o verificadas en cuentas de estado de contexto.
// 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?;
En el cliente JS, retirar las tarifas recolectadas fuera del mint
(getWithdrawWithheldTokensFromMintForConfidentialTransferFeeInstruction)
además requiere una prueba de igualdad y una prueba de rango verificadas en
cuentas de estado de contexto, por lo que sigue el mismo patrón de cuentas de
prueba que una transferencia confidencial.
Mint y quema confidenciales
La extensión ConfidentialMintBurn permite a la autoridad del mint emitir y
quemar suministro directamente contra saldos confidenciales, manteniendo el
suministro total cifrado. Un mint con esta extensión deshabilita la ruta pública
de depósito y retiro, ya que los tokens solo existen de forma confidencial.
Consulta la
documentación del protocolo
para el modelo completo.
El mint/quema confidencial es más sencillo a través del spl-token-client de
Rust, que genera las pruebas necesarias y secuencia las transacciones por ti.
El cliente JS @solana-program/token-2022 incluye los constructores de
instrucciones de bajo nivel (getConfidentialMintInstruction,
getConfidentialBurnInstruction y similares), pero no un asistente de alto
nivel que construya las pruebas, y no hay comandos de CLI, por lo que los
ejemplos a continuación son solo para Rust.
Inicializa la extensión al crear el mint, luego acuña, quema y reconcilia el suministro con el tiempo. La acuñación emite una cantidad cifrada en el saldo confidencial de un destinatario; la quema elimina una cantidad cifrada en una quema pendiente que luego se incorpora al suministro. Ambas operaciones generan pruebas como una transferencia confidencial.
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?;
Rota la clave de cifrado del suministro con
confidential_transfer_rotate_supply_elgamal_pubkey (la quema pendiente debe
ser cero primero), y actualiza el texto cifrado del suministro legible con
confidential_transfer_update_decrypt_supply.
Consideraciones operativas y de cumplimiento
- Custodia de la clave del auditor. Si configuras un auditor, la clave secreta del auditor es una clave de descifrado de alto valor. Almacénala y rótala con cuidado, y decide quién dentro de tu organización (o qué regulador) la custodia.
- Postura de cumplimiento. El análisis de direcciones y el análisis del grafo de contrapartes siguen funcionando porque las direcciones permanecen públicas. El monitoreo basado en montos depende de la clave del auditor o de la divulgación selectiva por parte de los titulares de cuentas. Define tu enfoque antes del lanzamiento.
- Incorporación de titulares. Configurar una cuenta confidencial requiere la firma del propietario. Para provisionar cuentas de usuarios de forma fluida, pídeles que registren una clave ElGamal una vez y utilicen la ruta del registro, descrita en la Guía de integración.
- Número de transacciones. Una transferencia confidencial actualmente abarca varias transacciones dependientes porque las pruebas superan el límite de tamaño de transacción actual. El formato de transacción v1 (disponible con Agave v4.2) eleva ese límite y se espera que permita una única transacción en cadena.
Is this page helpful?