Come creare un mint con l'estensione Confidential Transfer
L'estensione Confidential Transfer consente trasferimenti di token privati aggiungendo stato extra al mint account. Questa sezione spiega come creare un token mint con questa estensione abilitata.
Il seguente diagramma mostra i passaggi necessari per creare un mint con l'estensione Confidential Transfer:
Stato del Mint con Confidential Transfer
L'estensione aggiunge lo stato ConfidentialTransferMint al mint account:
#[repr(C)]#[derive(Clone, Copy, Debug, Default, PartialEq, Pod, Zeroable)]pub struct ConfidentialTransferMint {/// Authority to modify the `ConfidentialTransferMint` configuration and to/// approve new accounts (if `auto_approve_new_accounts` is true)////// The legacy Token Multisig account is not supported as the authoritypub authority: OptionalNonZeroPubkey,/// Indicate if newly configured accounts must be approved by the/// `authority` before they may be used by the user.////// * If `true`, no approval is required and new accounts may be used/// immediately/// * If `false`, the authority must approve newly configured accounts (see/// `ConfidentialTransferInstruction::ConfigureAccount`)pub auto_approve_new_accounts: PodBool,/// Authority to decode any transfer amount in a confidential transfer.pub auditor_elgamal_pubkey: OptionalNonZeroElGamalPubkey,}
Il ConfidentialTransferMint contiene tre campi di configurazione:
-
authority: L'account che ha il permesso di modificare le impostazioni del trasferimento riservato per il mint e di approvare nuovi account riservati se l'approvazione automatica è disabilitata.
-
auto_approve_new_accounts: Se impostato su true, gli utenti possono creare token account con i trasferimenti riservati abilitati per impostazione predefinita. Se impostato su false, l'authority deve approvare ogni nuovo token account prima che possa essere utilizzato per i trasferimenti riservati.
-
auditor_elgamal_pubkey: Un revisore opzionale che può decifrare gli importi dei trasferimenti nelle transazioni riservate, fornendo un meccanismo di conformità pur mantenendo la privacy rispetto al pubblico generale.
Istruzioni Necessarie
La creazione di un mint con Confidential Transfer abilitato richiede tre istruzioni in una singola transazione:
-
Creare il Mint Account: Richiamare l'istruzione
CreateAccountdel System Program per creare il mint account. -
Inizializzare l'Estensione Confidential Transfer: Richiamare l'istruzione ConfidentialTransferInstruction::InitializeMint del Token Extensions Program per configurare lo stato
ConfidentialTransferMintper il mint. -
Inizializzare il Mint: Richiamare l'istruzione
Instruction::InitializeMintdel Token Extensions Program per inizializzare lo stato standard del mint.
Sebbene sia possibile scrivere queste istruzioni manualmente, il crate
spl_token_client fornisce un metodo create_mint che costruisce e invia una
transazione con tutte e tre le istruzioni in un'unica chiamata di funzione, come
mostrato nell'esempio seguente.
Codice di Esempio
Il seguente codice illustra come creare un mint con l'estensione Confidential Transfer.
I trasferimenti riservati dipendono dal programma ZK ElGamal Proof, abilitato su
mainnet e devnet. Un solana-test-validator standard non lo abilita, ma un
validator locale con fork della mainnet come Surfpool
sì. Esegui l'esempio su uno di questi ambienti (il codice utilizza devnet) con
un payer finanziato, e sostituisci gli indirizzi placeholder di mint e account
con i tuoi.
Rust
fn main() -> Result<()> {let rpc_client = RpcClient::new_with_commitment(String::from("https://api.devnet.solana.com"),CommitmentConfig::confirmed(),);let payer = load_keypair()?;let mint = Keypair::new();let decimals: u8 = 2;// Allocate space for a mint that carries the ConfidentialTransferMint// extension, then fund it for rent exemption.let space =ExtensionType::try_calculate_account_len::<Mint>(&[ExtensionType::ConfidentialTransferMint])?;let rent = rpc_client.get_minimum_balance_for_rent_exemption(space)?;// The auditor ElGamal key lets the issuer decrypt transfer amounts for// compliance. Persist this key. Pass `None` to create a mint with no auditor.let auditor = ElGamalKeypair::new_rand();let auditor_pubkey: PodElGamalPubkey = (*auditor.pubkey()).into();let create_account_ix = system_instruction::create_account(&payer.pubkey(),&mint.pubkey(),rent,space as u64,&spl_token_2022::id(),);// The confidential-transfer extension must be initialized before the base// mint and cannot be added later.let init_confidential_ix = initialize_confidential_transfer_mint(&spl_token_2022::id(),&mint.pubkey(),Some(payer.pubkey()), // authority that can update confidential settingstrue, // auto-approve new accountsSome(auditor_pubkey),)?;let init_mint_ix = initialize_mint_base(&spl_token_2022::id(),&mint.pubkey(),&payer.pubkey(), // mint authorityNone, // freeze authoritydecimals,)?;let blockhash = rpc_client.get_latest_blockhash()?;let transaction = Transaction::new_signed_with_payer(&[create_account_ix, init_confidential_ix, init_mint_ix],Some(&payer.pubkey()),&[&payer, &mint],blockhash,);let signature = rpc_client.send_and_confirm_transaction(&transaction)?;println!("Created confidential mint {}: {signature}", mint.pubkey());Ok(())}fn load_keypair() -> Result<Keypair> {let keypair_path = dirs::home_dir().context("could not find home directory")?.join(".config/solana/id.json");let bytes: Vec<u8> = serde_json::from_reader(std::fs::File::open(keypair_path)?)?;let mut secret = [0u8; 32];secret.copy_from_slice(&bytes[0..32]);Ok(Keypair::new_from_array(secret))}
Typescript
const client = await createClient().use(signerFromFile(join(homedir(), ".config/solana/id.json"))).use(solanaRpc({rpcUrl: "https://api.devnet.solana.com"}));const payer = client.payer;const mint = await generateKeyPairSigner();// The auditor ElGamal key lets the issuer decrypt transfer amounts for// compliance. Persist it; omit `auditorElgamalPubkey` to create a mint with no// auditor.const auditor = await deriveElGamalKeypairForOwnerMint({signer: payer,owner: payer.address,mint: mint.address});const plan = getCreateMintInstructionPlan({payer,newMint: mint,decimals: 2,mintAuthority: payer,extensions: [{__kind: "ConfidentialTransferMint",authority: some(payer.address),autoApproveNewAccounts: true,auditorElgamalPubkey: some(auditor.elgamalPubkey)}]});const result = await client.sendTransaction(plan);console.log(`Created confidential mint ${mint.address}: ${result.context.signature}`);
Is this page helpful?