Mint Close Authority Nedir?
Token Extensions Program'ın MintCloseAuthority mint uzantısı, belirlenen
bir yetkinin mint hesabını kapatmasına ve mint'in toplam arzı sıfıra ulaştığında
rent'ini geri almasına olanak tanır.
Bu uzantı olmadan, bir mint account kapatılamaz.
- Toplam arz sıfır olmalıdır, bu nedenle bir mint kapatılmadan önce tüm token account'lardaki tüm token'lar yakılmalıdır
- Yalnızca yapılandırılmış kapatma yetkisi mint'i kapatabilir
Mint Nasıl Oluşturulur ve Kapatılır
Bir mint oluşturmak ve kapatmak için:
- Mint hesabı boyutunu ve mint ile
MintCloseAuthorityuzantısı için gerekli rent'i hesaplayın. CreateAccountile mint hesabını oluşturun,MintCloseAuthority'i başlatın ve mint'iInitializeMintile başlatın.- Toplam arz sıfır ise, mint account kapatma yetkisi tarafından imzalanarak
CloseAccountile kapatılabilir.
Hesap boyutunu hesaplayın
Temel mint artı MintCloseAuthority uzantısı için mint account boyutunu
hesaplayın. Bu, CreateAccount'da kullanılan boyuttur.
Rent'i hesaplayın
Mint artı MintCloseAuthority uzantısı için gereken boyutu kullanarak
rent'i hesaplayın.
Mint hesabını oluşturun
Hesaplanan alan ve lamport ile mint account oluşturun.
MintCloseAuthority'yi Başlatma
Mint üzerinde MintCloseAuthority uzantısını başlatın.
Mint'i başlatma
Aynı işlemde InitializeMint ile mint'i başlatın.
Talimat Sırası
InitializeMintCloseAuthority, InitializeMint'den önce gelmelidir.
CreateAccount, InitializeMintCloseAuthority ve
InitializeMint aynı işleme dahil edilmelidir.
Kaynak Referansı
| Öğe | Açıklama | Kaynak |
|---|---|---|
MintCloseAuthority | Arzı sıfıra ulaştığında bir mint'i kapatmasına izin verilen yetkiyi saklayan mint uzantısı. | Kaynak |
InitializeMintCloseAuthority | InitializeMint'den önce mint kapatma yetkisini başlatan talimat. | Kaynak |
CloseAccount | Toplam arz sıfıra ulaştıktan sonra mint hesabını kapatan temel token talimatı. | Kaynak |
process_initialize_mint_close_authority | MintCloseAuthority uzantısını başlatılmamış bir mint üzerine yazan işlemci mantığı. | Kaynak |
process_close_account | Kapatma yetkisine sahip mint'ler için sıfır arz kuralını uygulayan paylaşılan hesap kapatma işleyicisi. | Kaynak |
Typescript
Aşağıdaki Kit örneği, oluşturulan talimatları doğrudan kullanır.
@solana/web3.js ve @solana/spl-token kullanan eski örnekler referans için
dahil edilmiştir.
Kit
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);
Web3.js
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 pubkey9, // decimalsfeePayer.publicKey, // mint authorityfeePayer.publicKey, // freeze authorityTOKEN_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);
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, // lamportsmint_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(), // mintSome(&fee_payer.pubkey()), // close authority)?;let initialize_mint_instruction = initialize_mint(&TOKEN_2022_PROGRAM_ID, // token program&mint.pubkey(), // mint&fee_payer.pubkey(), // mint authoritySome(&fee_payer.pubkey()), // freeze authority9, // 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(())}
Is this page helpful?