Cách tạo mint với extension Confidential Transfer
Extension Confidential Transfer cho phép chuyển token riêng tư bằng cách thêm trạng thái bổ sung vào mint account. Phần này giải thích cách tạo một token mint với extension này được bật.
Sơ đồ sau đây mô tả các bước liên quan đến việc tạo mint với extension Confidential Transfer:
Trạng Thái Mint của Confidential Transfer
Extension này thêm trạng thái ConfidentialTransferMint vào 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,}
ConfidentialTransferMint chứa ba trường cấu hình:
-
authority: Tài khoản có quyền thay đổi cài đặt chuyển tiền bảo mật cho mint và phê duyệt các tài khoản bảo mật mới nếu tính năng tự động phê duyệt bị tắt.
-
auto_approve_new_accounts: Khi được đặt thành true, người dùng có thể tạo token account với tính năng chuyển tiền bảo mật được bật theo mặc định. Khi đặt thành false, authority phải phê duyệt từng token account mới trước khi có thể sử dụng cho các giao dịch chuyển tiền bảo mật.
-
auditor_elgamal_pubkey: Một kiểm toán viên tùy chọn có thể giải mã số tiền chuyển trong các giao dịch bảo mật, cung cấp cơ chế tuân thủ trong khi vẫn duy trì sự riêng tư so với công chúng.
Các Lệnh Cần Thiết
Tạo mint với Confidential Transfer được bật yêu cầu ba lệnh trong một giao dịch duy nhất:
-
Tạo Mint Account: Gọi lệnh
CreateAccountcủa System Program để tạo mint account. -
Khởi Tạo Extension Confidential Transfer: Gọi lệnh ConfidentialTransferInstruction::InitializeMint của Token Extensions Program để cấu hình trạng thái
ConfidentialTransferMintcho mint. -
Khởi Tạo Mint: Gọi lệnh
Instruction::InitializeMintcủa Token Extensions Program để khởi tạo trạng thái mint tiêu chuẩn.
Mặc dù bạn có thể viết các lệnh này thủ công, crate spl_token_client cung cấp
phương thức create_mint giúp xây dựng và gửi một giao dịch với cả ba lệnh
trong một lần gọi hàm duy nhất, như được minh họa trong ví dụ dưới đây.
Mã Ví Dụ
Đoạn mã sau đây minh họa cách tạo một mint với phần mở rộng Confidential Transfer.
Các giao dịch bảo mật phụ thuộc vào chương trình ZK ElGamal Proof, được bật trên
mainnet và devnet. Một solana-test-validator thông thường không bật tính năng
này, nhưng một validator cục bộ fork mainnet như
Surfpool thì có. Hãy chạy ví dụ trên một trong các môi
trường đó (mã sử dụng devnet) với một payer có đủ số dư, và thay thế các địa chỉ
mint và tài khoản giữ chỗ bằng địa chỉ của bạn.
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?