Przewodnik wydawcy Confidential Transfer

Wydawanie tokenów Confidential Transfer na Solanie

Ten przewodnik jest przeznaczony dla wydawców: zespołów tworzących i obsługujących mint Token-2022 korzystający z rozszerzenia Confidential Transfer. Omawia decyzje podejmowane podczas tworzenia mintu oraz operacje wykonywane przez cały jego okres użytkowania. Informacje o przepływie po stronie posiadacza (depozyt, zastosowanie, transfer, wypłata) znajdziesz na stronach krok po kroku, a informacje o obsłudze tych tokenów w produkcie — w Przewodniku integracji.

Poufne transfery utrzymują kwoty przelewów i salda kont w postaci zaszyfrowanej, pozostawiając adresy kont, mint i właścicieli publicznymi. Opierają się na programie ZK ElGamal Proof Program do weryfikacji dowodów w łańcuchu, dlatego mint jest używalny w klastrach, w których ten program jest włączony.

Decyzje podejmowane przy tworzeniu

Rozszerzenie Confidential Transfer musi zostać zainicjalizowane przed inicjalizacją minta i nie można go dodać później. Przy tworzeniu decydujesz o:

  • Polityka zatwierdzania: czy konta mogą dobrowolnie włączyć poufne transfery bez uprawnień (auto) lub muszą zostać zatwierdzone przez organ ds. poufnych transferów minta (manual).
  • Audytor: czy ustawić globalny klucz publiczny ElGamal audytora, aby wyznaczona strona mogła odszyfrować każdą kwotę transferu dla minta. Opcjonalne i można to zmienić później.
  • Opcjonalne rozszerzenia towarzyszące: poufne opłaty za transfer (w parze z rozszerzeniem opłat za transfer) oraz poufny mint/burn – oba opisane poniżej. Również muszą zostać zainicjalizowane przy tworzeniu.

Utwórz poufny mint

CLI ustawia politykę zatwierdzania za pomocą --enable-confidential-transfers auto lub manual; auto pozwala każdemu posiadaczowi skonfigurować własne konto, natomiast manual uzależnia to od zatwierdzenia przez organ ds. poufnych transferów (który domyślnie jest organem minta). Ścieżki klienta przyjmują te same ustawienia poprzez parametry ConfidentialTransferMint: organ, flagę automatycznego zatwierdzania i opcjonalny klucz audytora. Zarówno politykę zatwierdzania, jak i audytora można zmienić później (patrz Konfiguracja audytora); jedynie obecność samego rozszerzenia jest ustalana przy tworzeniu.

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

Konfiguracja audytora

Globalny audytor to klucz publiczny ElGamal przechowywany w mincie. Po ustawieniu każdy poufny transfer dodatkowo szyfruje swoją kwotę tym kluczem, dzięki czemu ktokolwiek posiada odpowiedni klucz prywatny, może odszyfrować wszystkie kwoty transferów dla minta. W ten sposób poufne transfery pozostają zgodne z wymogami audytu i zgodności: opinia publiczna nie widzi nic, audytor widzi wszystko.

Organ władzy ds. poufnych transferów może w dowolnym momencie ustawić, zmienić lub usunąć audytora. Ta sama operacja aktualizuje również politykę zatwierdzania. W CLI klucz audytora jest kodowaniem base64 klucza publicznego ElGamal; przekaż --auditor-pubkey none, aby go usunąć, oraz --approve-policy auto|manual, aby zmienić politykę.

Rotacja dotyczy wyłącznie przyszłych transferów. Kwoty w transakcjach już zapisanych w łańcuchu bloków pozostają zaszyfrowane dla klucza audytora, który był aktywny w momencie ich wykonania – dlatego zachowaj stare klucze audytora, jeśli chcesz odszyfrować historyczną aktywność.

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

Tajny klucz audytora umożliwia odszyfrowanie każdej kwoty transferu dla danego mint. Przechowuj go z taką samą starannością jak klucz podpisujący i zaplanuj jego rotację. Ustawienie audytora na None wyłącza widoczność kwot dla wszystkich z wyjątkiem właścicieli kont.

Zatwierdzanie kont (polityka manualna)

Przy polityce manualnego zatwierdzania konto skonfigurowane do poufnych transferów nie może przeprowadzać transakcji w sposób poufny, dopóki organ władzy ds. poufnych transferów go nie zatwierdzi. Daje to emitentom mechanizm kontroli dostępu dla uczestników z listy dozwolonych lub po weryfikacji KYC. CLI nie udostępnia polecenia zatwierdzania – zatwierdzenie odbywa się za pośrednictwem klienta.

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

Poufne opłaty za transfer

Jeśli Twój mint pobiera opłatę za transfer, a transfery są poufne, opłata również musi być pobierana w sposób poufny. Rozszerzenie ConfidentialTransferFeeConfig obsługuje tę funkcję i jest inicjalizowane podczas tworzenia mint wraz z rozszerzeniami opłaty za transfer i poufnych transferów.

Zatrzymane opłaty narastają w formie zaszyfrowanej na kontach odbiorców, są następnie zbierane do mint, a potem wypłacane przez organ władzy ds. wypłaty zatrzymanych środków. Każda kwota opłaty pozostaje zaszyfrowana przez cały czas. Żadna z tych operacji nie jest dostępna przez CLI. Tajny klucz ElGamal organu władzy ds. wypłaty zatrzymanych środków umożliwia odszyfrowanie kwot zatrzymanych opłat, co w połączeniu z publicznymi parametrami opłat może ujawnić informacje o kwotach transferów – dlatego traktuj ten klucz jako wrażliwy.

Zainicjalizuj konfigurację opłat

Dołącz to razem z ConfidentialTransferMint i konfiguracją opłat transferowych podczas tworzenia tego samego minta.

use spl_token_client::token::ExtensionInitializationParams;
ExtensionInitializationParams::ConfidentialTransferFeeConfig {
authority: Some(authority.pubkey().into()),
withdraw_withheld_authority_elgamal_pubkey: withdraw_withheld_elgamal_pubkey,
};

Zbieranie i wypłacanie wstrzymanych opłat

Zbieranie przenosi zaszyfrowane wstrzymane opłaty z kont do minta; wypłacanie przenosi je z minta na wybrane konto. Zaangażowane są dwie jednostki upoważnione, z których każda może różnić się od jednostki uprawnionej do minta:

  • Jednostka uprawniona do poufnych opłat transferowych (authority ustawiona na ConfidentialTransferFeeConfig) włącza lub wyłącza zbieranie.
  • Jednostka uprawniona do wypłacania wstrzymanych środków (z pola TransferFeeConfig rozszerzenia opłat transferowych) wypłaca zebrane opłaty z minta.

Wypłaty wymagają dowodu równości i dowodu zakresu, dostarczonych inline lub zweryfikowanych w kontach stanu kontekstu.

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

W kliencie JS wypłacanie zebranych opłat z minta (getWithdrawWithheldTokensFromMintForConfidentialTransferFeeInstruction) wymaga dodatkowo dowodu równości i dowodu zakresu zweryfikowanych w kontach stanu kontekstu, dlatego stosuje ten sam schemat kont dowodowych co poufny transfer.

Poufne mintowanie i spalanie

Rozszerzenie ConfidentialMintBurn pozwala jednostce uprawnionej do minta emitować i spalać podaż bezpośrednio na poufnych saldach, utrzymując całkowity zasób zaszyfrowany. Mint z tym rozszerzeniem wyłącza publiczną ścieżkę deponowania i wypłacania, ponieważ tokeny istnieją wyłącznie w sposób poufny. Zapoznaj się z dokumentacją protokołu dotyczącą pełnego modelu.

Poufne mintowanie/spalanie jest najłatwiejsze za pomocą biblioteki Rust spl-token-client, która generuje wymagane dowody i sekwencjonuje transakcje za Ciebie. Klient JS @solana-program/token-2022 udostępnia niskopoziomowe konstruktory instrukcji (getConfidentialMintInstruction, getConfidentialBurnInstruction i inne), ale nie zawiera wysokopoziomowego pomocnika budującego dowody i nie ma poleceń CLI, więc poniższe przykłady dotyczą wyłącznie Rust.

Zainicjuj rozszerzenie podczas tworzenia mint, a następnie emituj, spalaj i uzgadniaj podaż w czasie. Emisja wprowadza zaszyfrowaną kwotę do poufnego salda odbiorcy; spalanie usuwa zaszyfrowaną kwotę do oczekującego spalenia, które jest później uwzględniane w podaży. Obie operacje generują dowody podobnie jak poufny przelew.

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

Zmień klucz szyfrowania podaży za pomocą confidential_transfer_rotate_supply_elgamal_pubkey (oczekujące spalenie musi wynosić wpierw zero), a następnie odśwież czytelny tekst zaszyfrowanej podaży za pomocą confidential_transfer_update_decrypt_supply.

Kwestie operacyjne i związane ze zgodnością

  • Przechowywanie klucza audytora. Jeśli ustawisz audytora, jego klucz prywatny jest kluczem deszyfrującym o wysokiej wartości. Przechowuj go i rotuj ostrożnie, i zdecyduj, kto w Twojej organizacji (lub który organ regulacyjny) go posiada.
  • Podejście do zgodności. Weryfikacja adresów i analiza grafu kontrahentów nadal działają, ponieważ adresy pozostają publiczne. Monitorowanie oparte na kwotach zależy od klucza audytora lub selektywnego ujawnienia przez właścicieli kont. Zdecyduj o swoim podejściu przed uruchomieniem.
  • Onboarding posiadaczy. Konfiguracja poufnego konta wymaga podpisu właściciela. Aby sprawnie tworzyć konta dla użytkowników, poproś ich o jednorazową rejestrację klucza ElGamal i skorzystaj ze ścieżki rejestru opisanej w Przewodniku integracji.
  • Liczba transakcji. Poufny przelew obejmuje obecnie kilka zależnych transakcji, ponieważ dowody przekraczają obecny limit rozmiaru transakcji. Format transakcji v1 (wprowadzany wraz z Agave v4.2) podnosi ten limit i ma umożliwić przeprowadzenie pojedynczej transakcji onchain.

Is this page helpful?