Einen Token-Mint erstellen

So erstellen Sie einen Mint mit der Confidential Transfer-Erweiterung

Die Confidential Transfer-Erweiterung ermöglicht private Token-Transfers, indem dem mint account zusätzlicher Zustand hinzugefügt wird. In diesem Abschnitt wird erläutert, wie ein Token-Mint mit dieser aktivierten Erweiterung erstellt wird.

Das folgende Diagramm zeigt die Schritte zum Erstellen eines Mints mit der Confidential Transfer-Erweiterung:

Create Mint with Confidential Transfer Extension

Confidential Transfer Mint-Zustand

Die Erweiterung fügt den ConfidentialTransferMint Zustand zum mint account hinzu:

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,
}

Die ConfidentialTransferMint enthält drei Konfigurationsfelder:

  • authority: Das Konten, das die Berechtigung hat, die Confidential Transfer-Einstellungen für den Mint zu ändern und neue vertrauliche Konten zu genehmigen, wenn die automatische Genehmigung deaktiviert ist.

  • auto_approve_new_accounts: Wenn auf „true“ gesetzt, können Benutzer token accounts mit standardmäßig aktivierten Confidential Transfers erstellen. Bei „false“ muss die Autorität jedes neue token account genehmigen, bevor es für Confidential Transfers verwendet werden kann.

  • auditor_elgamal_pubkey: Ein optionaler Prüfer, der Transferbeträge in vertraulichen Transaktionen entschlüsseln kann, wodurch ein Compliance-Mechanismus bereitgestellt wird, während die Privatsphäre gegenüber der Öffentlichkeit gewahrt bleibt.

Erforderliche Anweisungen

Das Erstellen eines Mints mit aktiviertem Confidential Transfer erfordert drei Anweisungen in einer einzigen Transaktion:

  1. Mint-Konto erstellen: Rufen Sie die CreateAccount- Anweisungen des System Program auf, um das mint account zu erstellen.

  2. Confidential Transfer-Erweiterung initialisieren: Rufen Sie die ConfidentialTransferInstruction::InitializeMint- Anweisungen des Token Extensions Program auf, um den ConfidentialTransferMint-Zustand für den Mint zu konfigurieren.

  3. Mint initialisieren: Rufen Sie die Instruction::InitializeMint- Anweisungen des Token Extensions Program auf, um den Standard-Mint-Zustand zu initialisieren.

Sie könnten diese Anweisungen zwar manuell schreiben, aber das spl_token_client-Crate stellt eine create_mint-Methode bereit, die eine Transaktion mit allen drei Anweisungen in einem einzigen Funktionsaufruf erstellt und sendet, wie im folgenden Beispiel gezeigt.

Beispielcode

Der folgende Code zeigt, wie ein Mint mit der Confidential Transfer-Erweiterung erstellt wird.

Vertrauliche Transfers sind auf das ZK ElGamal Proof-Programm angewiesen, das auf Mainnet und Devnet aktiviert ist. Ein standardmäßiger solana-test-validator aktiviert es nicht, aber ein mainnet-forking lokaler validator wie Surfpool schon. Führen Sie das Beispiel gegen eines davon aus (der Code verwendet Devnet) mit einem finanzierten Zahler, und ersetzen Sie die Platzhalter-Mint- und Konten-Adressen durch Ihre eigenen.

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?

Inhaltsverzeichnis

Seite bearbeiten
© 2026 Solana Foundation. Alle Rechte vorbehalten.