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.
Disponibilidad
Las transferencias confidenciales requieren el Token-2022
program@v11.0.0
o posterior. Están disponibles en devnet hoy y está previsto habilitarlas en
mainnet en junio de 2026. El Token Extension Program se despliega de forma
independiente en cada clúster, así que confirma el despliegue en el clúster
que uses.
Decisiones que tomas en la creación
La extensión de Transferencia Confidencial debe inicializarse antes de que se inicialice el mint y no puede añadirse posteriormente. En el momento de la creación decides:
- Política de aprobación: si las cuentas pueden optar por las transferencias
confidenciales de forma sin permisos (
auto) o deben ser aprobadas por la autoridad de transferencia confidencial del mint (manual). - Auditor: si se establece una clave pública ElGamal de auditor global para que una parte designada pueda descifrar todos los montos de transferencia del mint. Opcional, y puede modificarse posteriormente.
- Extensiones complementarias opcionales: comisiones de transferencia confidencial (combinadas con la extensión de comisión de transferencia) y emisión/quema confidencial, ambas descritas a continuación. Estas también deben inicializarse en el momento de la creación.
Crear una acuñación 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 condiciones eso a la
aprobación de la autoridad de transferencia confidencial (que por defecto es la
autoridad de acuñación). Las rutas del cliente reciben 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 posteriormente (consulte
Configurar un auditor); solo la presencia de la propia
extensión queda fijada en el momento de la creación.
$ spl-token --program-id TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb create-token --enable-confidential-transfers auto
Configurar un auditor
Un auditor global es una clave pública ElGamal almacenada en la acuñación. 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 de la acuñación. Así es como las transferencias confidenciales siguen siendo compatibles con los requisitos de auditoría y cumplimiento: 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 en 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 importes de las transacciones ya registradas en la cadena permanecen cifrados con la clave de auditor que estaba activa en el momento de su ejecución, por lo que conserve las claves de auditor antiguas si necesita descifrar la actividad histórica.
$ spl-token update-confidential-transfer-settings <MINT_PUBKEY> --auditor-pubkey <AUDITOR_ELGAMAL_PUBKEY>
La clave secreta del auditor puede descifrar todos los importes de
transferencia de la acuñación. 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 importes para todos excepto para los propios titulares de
las cuentas.
Aprobar cuentas (política manual)
Con una política de aprobación manual, una cuenta configurada para transferencias confidenciales no puede realizar transacciones de forma confidencial hasta que la autoridad de transferencias confidenciales la apruebe. Esto le otorga a los emisores un control de acceso para participantes en lista 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 tu 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 transfieren al mint y luego son retiradas por la autoridad de retiro de comisiones retenidas. Todos los importes de las comisiones permanecen cifrados 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 retenidas puede descifrar los importes de las comisiones retenidas, lo cual, combinado con los parámetros públicos de comisiones, puede revelar información sobre los importes de las transferencias, por lo que debes tratar esa clave como información sensible.
Inicializar la configuración de comisiones
Incluye esto junto con ConfidentialTransferMint y la configuración de
comisiones por 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,};
Cosechar y retirar comisiones retenidas
La cosecha mueve las comisiones retenidas cifradas desde las cuentas hacia el mint; el retiro las saca del mint hacia una cuenta elegida. Intervienen dos autoridades, y cualquiera de ellas puede ser diferente a la autoridad del mint:
- La autoridad de comisiones de transferencia confidencial (el
authorityconfigurado enConfidentialTransferFeeConfig) habilita o deshabilita la cosecha. - La autoridad de retiro de comisiones retenidas (de la
TransferFeeConfigde la extensión de comisiones por transferencia) retira las comisiones cosechadas fuera del mint.
Los retiros requieren una prueba de igualdad y una prueba de rango, suministradas 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 comisiones recolectadas del mint
(getWithdrawWithheldTokensFromMintForConfidentialTransferFeeInstruction)
también 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 cuenta de
prueba que una transferencia confidencial.
Acuñación y quema confidencial
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.
La acuñación/quema confidencial es más sencilla a través del crate de Rust
spl-token-client, 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 helper de alto nivel que construya las pruebas, y no
hay comandos CLI, por lo que los ejemplos a continuación son solo en 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 posteriormente se incorpora al suministro. Ambas 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 son 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 aprovisionar cuentas de usuarios de forma fluida, haz 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 abarca actualmente varias transacciones dependientes porque las pruebas superan el límite de tamaño de transacción actual. El formato de transacción v1 (que llega con Agave v4.2) eleva ese límite y se espera que permita una única transacción en cadena.
Is this page helpful?