在 Solana 上发行机密转账代币
本指南面向发行者:负责创建和运营使用机密转账扩展的 Token-2022 铸币账户的团队。内容涵盖您在创建铸币账户时需要做出的决策,以及在铸币账户生命周期内需要执行的操作。有关持有者端流程(存入、应用、转账、提取),请参阅分步说明页面;有关在产品中支持这些代币,请参阅 集成指南。
机密转账在加密转账金额和账户余额的同时,保持账户地址、铸币账户和所有者公开可见。该功能依赖 ZK ElGamal 证明程序进行链上证明验证,因此铸币账户可在已启用该程序的集群上使用。
创建时的决策
机密转账扩展必须在铸币厂初始化之前完成初始化,且之后无法添加。创建时您需要决定:
- 审批策略:账户是否可以无需许可地自行选择加入机密转账(
auto),还是必须由铸币厂的机密转账权限方审批(manual)。 - 审计员:是否为铸币厂设置全局审计员 ElGamal pubkey,以便指定方可以解密该铸币厂的所有转账金额。此项为可选,且可在创建后更改。
- 可选配套扩展:机密转账费用(与转账费用扩展配合使用)以及机密铸币/销毁,详见下文。这些也必须在创建时完成初始化。
创建机密铸币厂
CLI 通过 --enable-confidential-transfers auto 或 manual 设置审批策略;auto
允许任何持有者自行配置账户,而 manual
则要求经由机密转账权限方审批(默认为铸币权限方)。客户端路径通过
ConfidentialTransferMint
参数传入相同的设置:权限方、自动审批标志以及可选的审计员密钥。审批策略和审计员均可在创建后更改(参见配置审计员);仅扩展本身是否存在在创建时固定。
$ spl-token --program-id TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb create-token --enable-confidential-transfers auto
配置审计员
全局审计员是存储在铸币厂上的 ElGamal pubkey。设置后,每笔机密转账都会额外使用该密钥对金额进行加密,因此持有相应私钥的人可以解密该铸币厂的所有转账金额。这正是机密转账与审计及合规要求保持兼容的方式:公众什么都看不到,而审计员则一览无余。
保密转账授权方可随时设置、轮换或清除审计员。同一操作也会更新审批策略。在 CLI 中,审计员密钥是 ElGamal 公钥的 base64 编码;传入
--auditor-pubkey none 可将其移除,传入 --approve-policy auto|manual
可更改策略。
轮换仅影响未来的转账。已上链交易中的金额将保持以执行时所用的审计员密钥加密,因此如需解密历史记录,请妥善保留旧审计员密钥。
$ spl-token update-confidential-transfer-settings <MINT_PUBKEY> --auditor-pubkey <AUDITOR_ELGAMAL_PUBKEY>
审计员私钥可解密该铸币账户的所有转账金额。请以与签名密钥同等的严格程度保管该密钥,并制定轮换计划。将审计员设置为
None 将禁用所有人对金额的可见性,账户所有者本身除外。
批准账户(手动策略)
在手动审批策略下,已配置保密转账的账户在获得保密转账授权方批准之前,无法进行保密交易。这为发行方提供了一道针对白名单或已完成 KYC 参与者的准入门控。CLI 不提供批准命令,因此批准操作需通过客户端完成。
token.confidential_transfer_approve_account(&token_account,&authority,&[&authority_keypair],).await?;
保密转账费用
如果您的铸币账户收取转账费用且转账为保密转账,则费用也必须以保密方式扣留。ConfidentialTransferFeeConfig
扩展负责处理此事,并在创建铸币账户时与转账费用和保密转账扩展一同初始化。
扣留的费用以加密形式累积在收款账户上,随后被归集至铸币账户,再由提取扣留授权方进行提取。每笔费用金额全程保持加密状态。这些操作均不通过 CLI 公开。提取扣留授权方的 ElGamal 私钥可解密被扣留的费用金额,结合公开的费用参数,可能揭示转账金额的相关信息,因此请将该密钥视为敏感信息妥善保管。
初始化费用配置
将此与 ConfidentialTransferMint 和转账费用配置一起包含在同一个铸币创建中。
use spl_token_client::token::ExtensionInitializationParams;ExtensionInitializationParams::ConfidentialTransferFeeConfig {authority: Some(authority.pubkey().into()),withdraw_withheld_authority_elgamal_pubkey: withdraw_withheld_elgamal_pubkey,};
收割并提取扣留费用
收割将加密的扣留费用从账户转移到铸币中;提取则将其从铸币转移到指定账户。此过程涉及两个权限方,两者均可与铸币权限不同:
- 机密转账费用权限(在
ConfidentialTransferFeeConfig上设置的authority)用于启用或禁用收割。 - 提取扣留权限(来自转账费用扩展的
TransferFeeConfig)用于将已收割的费用从铸币中提取出来。
提取需要提供等式证明和范围证明,可内联提供或通过上下文状态账户进行验证。
// 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?;
在 JS 客户端中,从铸币中提取已收割费用(getWithdrawWithheldTokensFromMintForConfidentialTransferFeeInstruction)还需要将等式证明和范围证明验证到上下文状态账户中,因此其遵循与机密转账相同的证明账户模式。
机密铸造与销毁
ConfidentialMintBurn
扩展允许铸币权限直接针对机密余额发行和销毁供应量,同时保持总供应量加密。启用此扩展的铸币将禁用公开存款和提款路径,因为代币始终以机密形式存在。完整模型请参阅协议文档。
机密铸造/销毁最简便的方式是通过 Rust
spl-token-client,它会自动生成所需证明并为您安排交易顺序。@solana-program/token-2022
JS
客户端提供了底层指令构建器(getConfidentialMintInstruction、getConfidentialBurnInstruction
等),但没有用于构建证明的高级辅助工具,也没有 CLI 命令,因此以下示例仅限
Rust。
在铸币创建时初始化扩展,然后随时间推移进行铸币、销毁并调节供应量。铸币将加密金额发行至接收方的机密余额;销毁则将加密金额移至待处理销毁池,稍后再并入供应量。两者均会像机密转账一样生成证明。
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?;
使用 confidential_transfer_rotate_supply_elgamal_pubkey
轮换供应加密密钥(待处理销毁量必须先归零),并使用
confidential_transfer_update_decrypt_supply 刷新可读的供应密文。
操作与合规注意事项
- 审计员密钥保管。 如果您设置了审计员,审计员私钥是一个高价值的解密密钥。请妥善存储和轮换,并确定组织内部(或哪个监管机构)持有该密钥。
- 合规立场。 地址筛查和交易对手图谱分析仍然有效,因为地址保持公开。基于金额的监控依赖于审计员密钥或账户持有人的选择性披露。请在上线前确定您的处理方案。
- 持有人引导。 配置机密账户需要持有人签名。为顺利为用户开通账户,请让他们注册一次 ElGamal 密钥并使用注册表路径,详见集成指南。
- 交易数量。 机密转账目前跨越数笔相互依赖的交易,因为证明超出了当前的交易大小限制。交易格式 v1(随 Agave v4.2 上线)将提高该限制,预计可实现单笔链上交易。
Is this page helpful?