Confidential Balancesイシュアーガイド

SolanaでのConfidential Balancesトークンの発行

このガイドはイシュアー向けです。Confidential Balancesを使用するToken-2022ミントを作成・運用するチームを対象としています。ミント作成時に行う意思決定と、ミントのライフサイクルを通じて実行する操作について説明します。ホルダー側のフロー(デポジット、適用、転送、引き出し)については、ステップバイステップのページを参照してください。また、プロダクトでこれらのトークンをサポートする方法については、インテグレーションガイドを参照してください。

Confidential Balancesは、アカウントアドレス、ミント、およびオーナーを公開したまま、転送金額とアカウント残高を暗号化します。この拡張機能はオンチェーンの証明検証にZK ElGamal Proof Programを使用するため、そのプログラムが有効なクラスターでのみミントを利用できます。

作成時に決定する事項

Confidential Balances拡張機能は、ミントが初期化される前に初期化する必要があり、後から追加することはできません。作成時に以下を決定します:

  • 承認ポリシー:アカウントがパーミッションレス(auto)でConfidential Balancesにオプトインできるか、またはミントのConfidential Balances権限者による承認(manual)が必要かどうか。
  • 監査者: ミントのすべての転送金額を指定された当事者が復号できるよう、グローバル監査者のElGamal pubkeyを設定するかどうか。任意設定であり、後から変更可能。
  • オプションの拡張機能: 秘密転送手数料(転送手数料拡張機能と組み合わせ)および秘密ミント/バーン。いずれも下記で説明します。これらも作成時に初期化する必要があります。

秘密ミントの作成

CLIは--enable-confidential-transfers autoまたはmanualで承認ポリシーを設定します。autoはすべてのホルダーが自分のアカウントを設定できるようにし、manualはConfidential Balances権限者(デフォルトはミント権限者)による承認を必要とします。クライアントパスでは、ConfidentialTransferMintパラメーター(権限者、自動承認フラグ、およびオプションの監査人キー)を通じて同じ設定を行います。承認ポリシーと監査人はいずれも後から変更できます(監査人の設定を参照)。変更できないのは、拡張機能そのものの存在のみで、作成時に固定されます。

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

監査者の設定

グローバル監査人とは、ミントに保存されたElGamalの公開鍵です。設定されている場合、すべての機密転送はその金額をこの鍵でも暗号化するため、対応する秘密鍵を持つ者がミントのすべての転送金額を復号できます。これにより、Confidential Balancesが監査およびコンプライアンス要件との互換性を保つ仕組みとなっています。一般には何も見えず、監査人はすべてを把握できます。

Confidential Balances権限者は、監査人をいつでも設定、ローテーション、または削除できます。同じ操作で承認ポリシーも更新されます。CLIでは監査人キーはElGamal公開鍵のbase64エンコードで指定します。削除するには--auditor-pubkey noneを渡し、ポリシーを変更するには--approve-policy auto|manualを使用します。

ローテーションは今後の転送にのみ影響します。すでにオンチェーンにあるトランザクションの金額は、実行時にアクティブだった監査人キーで暗号化されたまま保持されるため、過去のアクティビティを復号化する必要がある場合は、古い監査人キーを保持してください。

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

監査人の秘密鍵は、そのミントに対するすべての転送金額を復号化できます。署名鍵と同等の厳格さで管理し、ローテーションの計画を立ててください。監査人をNoneに設定すると、アカウント所有者本人を除く全員に対して金額の可視性が無効になります。

アカウントの承認(手動ポリシー)

手動承認ポリシーでは、Confidential Balances用に設定されたアカウントは、Confidential Balances権限者が承認するまで機密転送を実行できません。これにより、イシュアーはアローリストまたはKYC済みの参加者に対するゲートを設けることができます。CLIには承認コマンドが用意されていないため、承認はクライアントを通じて行います。

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

機密転送手数料

ミントに転送手数料が設定されており、転送が機密扱いの場合、手数料も機密として源泉徴収される必要があります。ConfidentialTransferFeeConfig拡張機能がこれを処理し、転送手数料とConfidential Balances拡張機能の両方とともに、ミント作成時に初期化されます。

差し引かれた手数料は受信者アカウント上で暗号化されたまま蓄積され、ミントに回収された後、差し引き額引き出し権限者によって引き出されます。すべての手数料金額は処理全体を通じて暗号化されたままです。これらは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,
};

保留手数料のハーベストと引き出し

ハーベストは、アカウントから暗号化された保留手数料をミントに移動させます。引き出しは、それらをミントから選択したアカウントへ移動させます。2つの権限が関与し、どちらもミント権限とは異なる場合があります:

  • 機密送金手数料権限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 None
None, // 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クライアントには低レベルの命令ビルダー(getConfidentialMintInstructiongetConfidentialBurnInstruction など)が含まれていますが、証明を構築する高レベルのヘルパーはなく、CLIコマンドも存在しないため、以下の例はRustのみです。

拡張機能をミント作成時に初期化し、その後、ミント、バーン、およびサプライの調整を継続的に行います。ミントは暗号化された金額を受取人のコンフィデンシャル残高に発行し、バーンは暗号化された金額をペンディングバーンに移し、後にサプライに折り込まれます。どちらもコンフィデンシャル転送と同様のプルーフを生成します。

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

confidential_transfer_rotate_supply_elgamal_pubkey を使用してサプライ暗号化キーをローテーションし(先にペンディングバーンをゼロにする必要があります)、confidential_transfer_update_decrypt_supply を使用して読み取り可能なサプライ暗号文を更新します。

運用およびコンプライアンスに関する考慮事項

  • 監査人キーの管理。 監査人を設定した場合、監査人の秘密鍵は高価値の復号化キーです。慎重に保管およびローテーションし、組織内の誰(またはどの規制機関)が保持するかを決定してください。
  • コンプライアンス体制。 アドレスが公開されたままであるため、アドレスのスクリーニングおよびカウンターパーティグラフ分析は引き続き機能します。金額ベースのモニタリングは、監査人キーまたはアカウントオーナーによる選択的開示に依存します。ローンチ前にアプローチを決定してください。
  • ホルダーのオンボーディング。 コンフィデンシャルアカウントの設定にはオーナーの署名が必要です。ユーザーのアカウントをスムーズにプロビジョニングするには、ElGamalキーを一度登録させ、インテグレーションガイドに記載のレジストリパスを使用してください。
  • トランザクション数。 コンフィデンシャル転送は現在、プルーフが現在のトランザクションサイズ制限を超えるため、複数の依存トランザクションにまたがっています。トランザクションフォーマットv1(Agave v4.2とともにリリース予定)はその制限を引き上げ、単一のオンチェーントランザクションを可能にすることが期待されています。

Is this page helpful?

© 2026 Solana Foundation. 無断転載を禁じます。