إغلاق العملة

ما هي صلاحية إغلاق السك؟

يتيح ملحق MintCloseAuthority في Token Extensions Program لصلاحية محددة إغلاق حساب السك واستعادة الإيجار الخاص به بمجرد وصول إجمالي المعروض من السك إلى الصفر.

بدون هذا الملحق، لا يمكن إغلاق حساب السك.

  • يجب أن يكون إجمالي المعروض صفراً، لذا يجب حرق جميع الرموز في جميع حسابات الرموز قبل إغلاق حساب السك
  • فقط صلاحية الإغلاق المُكوَّنة يمكنها إغلاق السك

كيفية إنشاء وإغلاق حساب السك

لإنشاء وإغلاق حساب السك:

  1. احسب حجم حساب السك والإيجار المطلوب لحساب السك وملحق MintCloseAuthority.
  2. أنشئ حساب السك باستخدام CreateAccount، وقم بتهيئة MintCloseAuthority، وقم بتهيئة السك باستخدام InitializeMint.
  3. إذا كان إجمالي المعروض صفراً، يمكن إغلاق حساب السك باستخدام CloseAccount، موقعاً من قبل صلاحية الإغلاق.

احسب حجم الحساب

احسب حجم حساب السك للسك الأساسي بالإضافة إلى ملحق MintCloseAuthority. هذا هو الحجم المستخدم في CreateAccount.

احسب الإيجار

احسب الإيجار باستخدام الحجم المطلوب للسك بالإضافة إلى ملحق MintCloseAuthority.

أنشئ حساب السك

أنشئ حساب mint account باستخدام المساحة المحسوبة وعدد lamport.

تهيئة MintCloseAuthority

قم بتهيئة امتداد MintCloseAuthority على حساب mint.

تهيئة حساب mint

قم بتهيئة حساب mint باستخدام InitializeMint في نفس المعاملة.

احسب حجم الحساب

احسب حجم حساب السك للسك الأساسي بالإضافة إلى ملحق MintCloseAuthority. هذا هو الحجم المستخدم في CreateAccount.

احسب الإيجار

احسب الإيجار باستخدام الحجم المطلوب للسك بالإضافة إلى ملحق MintCloseAuthority.

أنشئ حساب السك

أنشئ حساب mint account باستخدام المساحة المحسوبة وعدد lamport.

تهيئة 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تعليمة الرمز الأساسية التي تغلق حساب mint بعد وصول الإمداد الكلي إلى الصفر.المصدر
process_initialize_mint_close_authorityمنطق المعالج الذي يكتب امتداد MintCloseAuthority على حساب mint غير مهيأ.المصدر
process_close_accountمعالج إغلاق الحساب المشترك الذي يفرض قاعدة الإمداد الصفري لحسابات mint التي لديها صلاحية الإغلاق.المصدر

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 مؤسسة سولانا.
جميع الحقوق محفوظة.
تواصل معنا