Κλείσιμο Mint

Τι Είναι το Mint Close Authority;

Η επέκταση mint MintCloseAuthority του Token Extensions Program επιτρέπει σε μια καθορισμένη αρχή να κλείσει έναν λογαριασμό mint και να ανακτήσει το rent του μόλις η συνολική προσφορά του mint φτάσει στο μηδέν.

Χωρίς αυτή την επέκταση, ένας λογαριασμός mint δεν μπορεί να κλείσει.

  • Η συνολική προσφορά πρέπει να είναι μηδέν, επομένως όλα τα tokens σε όλους τους λογαριασμούς token πρέπει να καταστραφούν προτού κλείσει ένα mint
  • Μόνο η διαμορφωμένη αρχή κλεισίματος μπορεί να κλείσει το mint

Πώς να Δημιουργήσετε και να Κλείσετε ένα Mint

Για να δημιουργήσετε και να κλείσετε ένα mint:

  1. Υπολογίστε το μέγεθος του λογαριασμού mint και το rent που απαιτείται για το mint και την επέκταση MintCloseAuthority.
  2. Δημιουργήστε τον λογαριασμό mint με CreateAccount, αρχικοποιήστε το MintCloseAuthority, και αρχικοποιήστε το mint με InitializeMint.
  3. Εάν η συνολική προσφορά είναι μηδέν, ο λογαριασμός mint μπορεί να κλείσει με CloseAccount, υπογεγραμμένο από την αρχή κλεισίματος.

Υπολογισμός μεγέθους λογαριασμού

Υπολογίστε το μέγεθος του λογαριασμού mint για το βασικό mint συν την επέκταση MintCloseAuthority. Αυτό είναι το μέγεθος που χρησιμοποιείται στο CreateAccount.

Υπολογισμός rent

Υπολογίστε το rent χρησιμοποιώντας το μέγεθος που απαιτείται για το mint συν την επέκταση MintCloseAuthority.

Δημιουργία του λογαριασμού mint

Δημιουργήστε τον λογαριασμό mint με τον υπολογισμένο χώρο και lamports.

Αρχικοποίηση MintCloseAuthority

Αρχικοποιήστε την επέκταση MintCloseAuthority στο mint.

Αρχικοποίηση του mint

Αρχικοποιήστε το mint με InitializeMint στην ίδια συναλλαγή.

Υπολογισμός μεγέθους λογαριασμού

Υπολογίστε το μέγεθος του λογαριασμού mint για το βασικό mint συν την επέκταση MintCloseAuthority. Αυτό είναι το μέγεθος που χρησιμοποιείται στο CreateAccount.

Υπολογισμός rent

Υπολογίστε το rent χρησιμοποιώντας το μέγεθος που απαιτείται για το mint συν την επέκταση MintCloseAuthority.

Δημιουργία του λογαριασμού mint

Δημιουργήστε τον λογαριασμό mint με τον υπολογισμένο χώρο και lamports.

Αρχικοποίηση MintCloseAuthority

Αρχικοποιήστε την επέκταση MintCloseAuthority στο mint.

Αρχικοποίηση του mint

Αρχικοποιήστε το mint με InitializeMint στην ίδια συναλλαγή.

Example
const client = await createClient()
.use(generatedPayer())
.use(
solanaRpc({
rpcUrl: "http://localhost:8899",
rpcSubscriptionsUrl: "ws://localhost:8900"
})
)
.use(rpcAirdrop())
.use(airdropPayer(lamports(1_000_000_000n)));
const mint = await generateKeyPairSigner();
const destination = await generateKeyPairSigner();
const mintCloseAuthorityExtension = extension("MintCloseAuthority", {
closeAuthority: client.payer.address
});
const mintSpace = BigInt(getMintSize([mintCloseAuthorityExtension]));

Σειρά Εντολών

Το InitializeMintCloseAuthority πρέπει να προηγείται του InitializeMint. Τα CreateAccount, InitializeMintCloseAuthority και InitializeMint πρέπει να περιλαμβάνονται στην ίδια συναλλαγή.

Αναφορά Πηγής

ΣτοιχείοΠεριγραφήΠηγή
MintCloseAuthorityΕπέκταση mint που αποθηκεύει την εξουσιοδότηση που επιτρέπεται να κλείσει ένα mint μόλις η προσφορά του φτάσει το μηδέν.Πηγή
InitializeMintCloseAuthorityΕντολή που αρχικοποιεί την εξουσιοδότηση κλεισίματος mint πριν από το InitializeMint.Πηγή
CloseAccountΒασική εντολή token που κλείνει τον λογαριασμό mint αφού η συνολική προσφορά φτάσει το μηδέν.Πηγή
process_initialize_mint_close_authorityΛογική επεξεργασίας που γράφει την επέκταση MintCloseAuthority σε ένα μη αρχικοποιημένο mint.Πηγή
process_close_accountΚοινός χειριστής κλεισίματος λογαριασμού που επιβάλλει τον κανόνα μηδενικής προσφοράς για mints με εξουσιοδότηση κλεισίματος.Πηγή

Typescript

Το παρακάτω παράδειγμα Kit χρησιμοποιεί τις δημιουργημένες εντολές απευθείας. Παραδείγματα παλαιότερου τύπου που χρησιμοποιούν @solana/web3.js και @solana/spl-token περιλαμβάνονται για αναφορά.

Kit

Instructions
import { lamports, createClient, generateKeyPairSigner } from "@solana/kit";
import { solanaRpc, rpcAirdrop } from "@solana/kit-plugin-rpc";
import { generatedPayer, airdropPayer } from "@solana/kit-plugin-signer";
import { getCreateAccountInstruction } from "@solana-program/system";
import {
extension,
findAssociatedTokenPda,
getBurnCheckedInstruction,
getCloseAccountInstruction,
getCreateAssociatedTokenInstructionAsync,
getInitializeMintCloseAuthorityInstruction,
getInitializeMintInstruction,
getMintSize,
getMintToCheckedInstruction,
TOKEN_2022_PROGRAM_ADDRESS
} from "@solana-program/token-2022";
const client = await createClient()
.use(generatedPayer())
.use(
solanaRpc({
rpcUrl: "http://localhost:8899",
rpcSubscriptionsUrl: "ws://localhost:8900"
})
)
.use(rpcAirdrop())
.use(airdropPayer(lamports(1_000_000_000n)));
const mint = await generateKeyPairSigner();
const destination = await generateKeyPairSigner();
const mintCloseAuthorityExtension = extension("MintCloseAuthority", {
closeAuthority: client.payer.address
});
const mintSpace = BigInt(getMintSize([mintCloseAuthorityExtension]));
const mintRent = await client.rpc
.getMinimumBalanceForRentExemption(mintSpace)
.send();
await client.sendTransaction([
getCreateAccountInstruction({
payer: client.payer,
newAccount: mint,
lamports: mintRent,
space: mintSpace,
programAddress: TOKEN_2022_PROGRAM_ADDRESS
}),
getInitializeMintCloseAuthorityInstruction({
mint: mint.address, // Mint account that stores the MintCloseAuthority extension.
closeAuthority: client.payer.address // Authority allowed to close the mint.
}),
getInitializeMintInstruction({
mint: mint.address,
decimals: 0,
mintAuthority: client.payer.address,
freezeAuthority: client.payer.address
})
]);
const [token] = await findAssociatedTokenPda({
mint: mint.address,
owner: client.payer.address,
tokenProgram: TOKEN_2022_PROGRAM_ADDRESS
});
await client.sendTransaction([
await getCreateAssociatedTokenInstructionAsync({
payer: client.payer,
mint: mint.address,
owner: client.payer.address
}),
getMintToCheckedInstruction({
mint: mint.address,
token,
mintAuthority: client.payer,
amount: 1n,
decimals: 0
})
]);
await client.sendTransaction([
getBurnCheckedInstruction({
mint: mint.address,
account: token,
authority: client.payer,
amount: 1n,
decimals: 0
}),
getCloseAccountInstruction({
account: mint.address, // Mint account to close.
destination: destination.address, // Account receiving the reclaimed lamports.
owner: client.payer // Close authority signing the instruction.
})
]);
const mintInfo = await client.rpc.getAccountInfo(mint.address).send();
console.log("Mint Address:", mint.address);
console.log("Destination Address:", destination.address);
console.log("Mint Closed:", mintInfo.value === null);
Console
Click to execute the code.

Web3.js

Instructions
import {
Connection,
Keypair,
sendAndConfirmTransaction,
SystemProgram,
Transaction,
LAMPORTS_PER_SOL
} from "@solana/web3.js";
import {
createInitializeMintInstruction,
ExtensionType,
getMintLen,
createInitializeMintCloseAuthorityInstruction,
TOKEN_2022_PROGRAM_ID,
createCloseAccountInstruction
} from "@solana/spl-token";
const connection = new Connection("http://localhost:8899", "confirmed");
const latestBlockhash = await connection.getLatestBlockhash();
const feePayer = Keypair.generate();
const destination = Keypair.generate();
const airdropSignature = await connection.requestAirdrop(
feePayer.publicKey,
5 * LAMPORTS_PER_SOL
);
await connection.confirmTransaction({
blockhash: latestBlockhash.blockhash,
lastValidBlockHeight: latestBlockhash.lastValidBlockHeight,
signature: airdropSignature
});
const mint = Keypair.generate();
const extensions = [ExtensionType.MintCloseAuthority];
const mintLength = getMintLen(extensions);
const mintRent = await connection.getMinimumBalanceForRentExemption(mintLength);
const createAccountInstruction = SystemProgram.createAccount({
fromPubkey: feePayer.publicKey,
newAccountPubkey: mint.publicKey,
space: mintLength,
lamports: mintRent,
programId: TOKEN_2022_PROGRAM_ID
});
const initializeMintCloseAuthorityInstruction =
createInitializeMintCloseAuthorityInstruction(
mint.publicKey, // Mint account that stores the MintCloseAuthority extension.
feePayer.publicKey, // Authority allowed to close the mint.
TOKEN_2022_PROGRAM_ID // Token program that owns the mint.
);
const initializeMintInstruction = createInitializeMintInstruction(
mint.publicKey, // mint pubkey
9, // decimals
feePayer.publicKey, // mint authority
feePayer.publicKey, // freeze authority
TOKEN_2022_PROGRAM_ID
);
const transaction = new Transaction({
feePayer: feePayer.publicKey,
blockhash: latestBlockhash.blockhash,
lastValidBlockHeight: latestBlockhash.lastValidBlockHeight
}).add(
createAccountInstruction,
initializeMintCloseAuthorityInstruction,
initializeMintInstruction
);
const transactionSignature = await sendAndConfirmTransaction(
connection,
transaction,
[feePayer, mint]
);
console.log("Mint Address:", mint.publicKey.toBase58());
console.log("Transaction Signature:", transactionSignature);
const latestBlockhash2 = await connection.getLatestBlockhash();
const closeMintInstruction = createCloseAccountInstruction(
mint.publicKey, // Mint account to close.
destination.publicKey, // Account receiving the reclaimed lamports.
feePayer.publicKey, // Close authority signing the instruction.
[], // Additional multisig signers.
TOKEN_2022_PROGRAM_ID // Token program that owns the mint.
);
const closeMintTransaction = new Transaction({
feePayer: feePayer.publicKey,
blockhash: latestBlockhash2.blockhash,
lastValidBlockHeight: latestBlockhash2.lastValidBlockHeight
}).add(closeMintInstruction);
const transactionSignature3 = await sendAndConfirmTransaction(
connection,
closeMintTransaction,
[feePayer]
);
console.log("\nDestination Address:", destination.publicKey.toBase58());
console.log("Transaction Signature:", transactionSignature3);
Console
Click to execute the code.

Rust

Rust
use anyhow::Result;
use solana_client::nonblocking::rpc_client::RpcClient;
use solana_commitment_config::CommitmentConfig;
use solana_sdk::{
signature::{Keypair, Signer},
transaction::Transaction,
};
use solana_system_interface::instruction::create_account;
use spl_token_2022_interface::{
extension::{
mint_close_authority::MintCloseAuthority, BaseStateWithExtensions, ExtensionType,
StateWithExtensions,
},
instruction::{close_account, initialize_mint, initialize_mint_close_authority},
state::Mint,
ID as TOKEN_2022_PROGRAM_ID,
};
#[tokio::main]
async fn main() -> Result<()> {
let client = RpcClient::new_with_commitment(
String::from("http://localhost:8899"),
CommitmentConfig::confirmed(),
);
let fee_payer = Keypair::new();
let destination = Keypair::new();
let airdrop_signature = client
.request_airdrop(&fee_payer.pubkey(), 5_000_000_000)
.await?;
loop {
let confirmed = client.confirm_transaction(&airdrop_signature).await?;
if confirmed {
break;
}
}
let mint = Keypair::new();
let mint_space =
ExtensionType::try_calculate_account_len::<Mint>(&[ExtensionType::MintCloseAuthority])?;
let mint_rent = client
.get_minimum_balance_for_rent_exemption(mint_space)
.await?;
let create_account_instruction = create_account(
&fee_payer.pubkey(), // payer
&mint.pubkey(), // new account (mint)
mint_rent, // lamports
mint_space as u64, // space
&TOKEN_2022_PROGRAM_ID, // program id
);
let initialize_close_mint_instruction = initialize_mint_close_authority(
&TOKEN_2022_PROGRAM_ID, // token program
&mint.pubkey(), // mint
Some(&fee_payer.pubkey()), // close authority
)?;
let initialize_mint_instruction = initialize_mint(
&TOKEN_2022_PROGRAM_ID, // token program
&mint.pubkey(), // mint
&fee_payer.pubkey(), // mint authority
Some(&fee_payer.pubkey()), // freeze authority
9, // decimals
)?;
let transaction = Transaction::new_signed_with_payer(
&[
create_account_instruction,
initialize_close_mint_instruction,
initialize_mint_instruction,
],
Some(&fee_payer.pubkey()),
&[&fee_payer, &mint],
client.get_latest_blockhash().await?,
);
client.send_and_confirm_transaction(&transaction).await?;
println!("Mint Address: {}", mint.pubkey());
let mint_account = client.get_account(&mint.pubkey()).await?;
let mint_state = StateWithExtensions::<Mint>::unpack(&mint_account.data)?;
let mint_extension_types = mint_state.get_extension_types()?;
println!("\nMint extensions enabled: {:?}", mint_extension_types);
let mint_close_authority = mint_state.get_extension::<MintCloseAuthority>()?;
println!("\n{:#?}", mint_close_authority);
let close_mint_instruction = close_account(
&TOKEN_2022_PROGRAM_ID, // Token program that owns the mint.
&mint.pubkey(), // Mint account to close.
&destination.pubkey(), // Account receiving the reclaimed lamports.
&fee_payer.pubkey(), // Close authority signing the instruction.
&[&fee_payer.pubkey()], // Additional multisig signers.
)?;
let transaction = Transaction::new_signed_with_payer(
&[close_mint_instruction],
Some(&fee_payer.pubkey()),
&[&fee_payer],
client.get_latest_blockhash().await?,
);
client.send_and_confirm_transaction(&transaction).await?;
match client.get_account(&mint.pubkey()).await {
Ok(_) => println!("\nMint account still exists (unexpected)"),
Err(e) => println!("\nMint account successfully closed: {:#?}", e),
}
Ok(())
}
Console
Click to execute the code.

Is this page helpful?

Πίνακας Περιεχομένων

Επεξεργασία Σελίδας

Διαχειρίζεται από

© 2026 Ίδρυμα Solana.
Με επιφύλαξη παντός δικαιώματος.
Συνδεθείτε