Membuat token mint

Cara membuat mint dengan Confidential Balances

Confidential Balances memungkinkan transfer token secara privat dengan menambahkan state tambahan ke mint account. Bagian ini menjelaskan cara membuat token mint dengan extension yang diperlukan diaktifkan.

Diagram berikut menunjukkan langkah-langkah yang terlibat dalam membuat mint dengan extension Confidential Balances:

Create Mint with Confidential Balances

State Mint Confidential Balances

Ekstensi ini menambahkan state ConfidentialTransferMint ke mint account:

Confidential Mint State
#[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 authority
pub 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 memiliki tiga bidang konfigurasi:

  • authority: Akun yang memiliki izin untuk mengubah pengaturan Confidential Balances pada mint dan menyetujui token account baru jika persetujuan otomatis dinonaktifkan.

  • auto_approve_new_accounts: Ketika diatur ke true, pengguna dapat membuat token account dengan Confidential Balances yang diaktifkan secara default. Ketika false, authority harus menyetujui setiap token account baru sebelum dapat digunakan untuk transfer konfidensial.

  • auditor_elgamal_pubkey: Auditor opsional yang dapat mendekripsi jumlah transfer dalam transaksi rahasia, menyediakan mekanisme kepatuhan sambil tetap menjaga privasi dari publik umum.

Instruksi yang Diperlukan

Membuat mint dengan Confidential Balances yang diaktifkan memerlukan tiga instruksi dalam satu transaksi:

  1. Buat Mint Account: Panggil instruksi CreateAccount dari System Program untuk membuat mint account.

  2. Initialize Confidential Balances: Memanggil instruksi ConfidentialTransferInstruction::InitializeMint dari Token Extension Program untuk mengonfigurasi state ConfidentialTransferMint pada mint.

  3. Inisialisasi Mint: Panggil instruksi Instruction::InitializeMint dari Token Extensions Program untuk menginisialisasi state mint standar.

Meskipun Anda dapat menulis instruksi-instruksi ini secara manual, crate spl_token_client menyediakan metode create_mint yang membangun dan mengirimkan transaksi dengan ketiga instruksi dalam satu pemanggilan fungsi, seperti yang ditunjukkan pada contoh di bawah ini.

Contoh Kode

Kode berikut mendemonstrasikan cara membuat mint dengan Confidential Balances yang diaktifkan.

Confidential Balances bergantung pada program ZK ElGamal Proof, yang diaktifkan pada mainnet dan devnet. solana-test-validator standar tidak mengaktifkannya, tetapi validator lokal yang melakukan fork mainnet seperti Surfpool mendukungnya. Jalankan contoh ini pada salah satu dari keduanya (kode menggunakan devnet) dengan payer yang memiliki saldo, dan ganti alamat mint dan akun placeholder dengan milik Anda sendiri.

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 settings
true, // auto-approve new accounts
Some(auditor_pubkey),
)?;
let init_mint_ix = initialize_mint_base(
&spl_token_2022::id(),
&mint.pubkey(),
&payer.pubkey(), // mint authority
None, // freeze authority
decimals,
)?;
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?

Daftar Isi

Edit Halaman
© 2026 Yayasan Solana. Semua hak dilindungi.