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

Випуск токенів із конфіденційними балансами на Solana

Цей посібник призначений для емітентів — команд, які створюють і обслуговують монетний двір Token-2022 з підтримкою конфіденційних балансів. У ньому розглядаються рішення, які ухвалюються під час створення монетного двору, а також операції, що виконуються протягом усього його існування. Інформацію про дії з боку власника (депозит, застосування, переказ, виведення) дивіться в покрокових інструкціях, а щодо підтримки цих токенів у продукті — у Посібнику з інтеграції.

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

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

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

  • Політика підтвердження: чи можуть рахунки підключатися до конфіденційних балансів без дозволу (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?