Посібник емітента конфіденційних переказів

Випуск токенів Confidential Transfer на Solana

Цей посібник призначений для емітентів: команд, які створюють та обслуговують мінт Token-2022 з розширенням Confidential Transfer. Він охоплює рішення, які ви приймаєте під час створення мінту, та операції, які ви виконуєте протягом усього його циклу. Для огляду дій з боку власника (депозит, застосування, переказ, виведення) зверніться до покрокових сторінок, а для підтримки цих токенів у продукті — до Посібника з інтеграції.

Конфіденційні перекази зберігають суми переказів та залишки на рахунках у зашифрованому вигляді, лишаючи адреси рахунків, мінт і власників загальнодоступними. Вони покладаються на ZK ElGamal Proof Program для верифікації доказів у мережі, тому мінт можна використовувати на кластерах, де ця програма увімкнена.

Доступність

Конфіденційні перекази потребують Token-2022 program@v11.0.0 або новішої версії. Сьогодні вони доступні в devnet і заплановані до увімкнення в mainnet у червні 2026 року. Token Extension Program розгортається окремо на кожному кластері, тому підтвердьте розгортання на потрібному вам кластері.

Рішення, які ви приймаєте під час створення

Розширення Confidential Transfer необхідно ініціалізувати до ініціалізації мінту, і додати його пізніше неможливо. Під час створення ви вирішуєте:

  • Політика підтвердження: чи можуть рахунки підключатися до конфіденційних переказів без дозволу (auto), або ж потребують схвалення від органу конфіденційних переказів мінту (manual).
  • Аудитор: чи встановлювати глобальний ElGamal публічний ключ аудитора, щоб призначена сторона могла розшифровувати кожну суму переказу для мінту. Необов'язково, можна змінити пізніше.
  • Додаткові супутні розширення: комісії за конфіденційні перекази (у поєднанні з розширенням комісії за переказ) та конфіденційний мінтинг/спалювання — обидва розглянуті нижче. Їх також необхідно ініціалізувати під час створення.

Створення конфіденційного мінту

CLI встановлює політику підтвердження за допомогою --enable-confidential-transfers auto або manual; auto дозволяє будь-якому власнику самостійно налаштувати свій акаунт, тоді як manual вимагає затвердження від органу конфіденційних переказів (яким за замовчуванням є орган мінту). Клієнтські шляхи передають ті самі налаштування через параметри ConfidentialTransferMint: орган, прапорець автозатвердження та необов'язковий ключ аудитора. Як політику підтвердження, так і аудитора можна змінити пізніше (див. Налаштування аудитора); фіксованою при створенні залишається лише наявність самого розширення.

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

Налаштування аудитора

Глобальний аудитор — це публічний ключ ElGamal, збережений у мінті. Якщо його встановлено, кожен конфіденційний переказ додатково шифрує свою суму цим ключем, тому власник відповідного секретного ключа може розшифрувати всі суми переказів для цього мінту. Саме так конфіденційні перекази залишаються сумісними з вимогами аудиту та дотримання нормативних вимог: публіка не бачить нічого, аудитор бачить усе.

Орган конфіденційних переказів може встановити, змінити або видалити аудитора у будь-який час. Та сама операція також оновлює політику підтвердження. У CLI ключ аудитора є base64-кодуванням публічного ключа ElGamal; передайте --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,
};

Збір та виведення утриманих комісій

Збір переміщує зашифровані утримані комісії з акаунтів до монетного двору; виведення переміщує їх із монетного двору на обраний акаунт. Задіяні два органи, кожен із яких може відрізнятися від органу монетного двору:

  • Орган конфіденційних комісій за переказ (authority, встановлений у ConfidentialTransferFeeConfig) вмикає або вимикає збір.
  • Орган виведення утриманих коштів (з поля 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, який генерує необхідні докази та послідовно виконує транзакції за вас. JS-клієнт @solana-program/token-2022 містить низькорівневі конструктори інструкцій (getConfidentialMintInstruction, getConfidentialBurnInstruction та інші), але не має високорівневого помічника для побудови доказів, і команди 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?