Τι Είναι το Permissioned Burn;
Η επέκταση mint PermissionedBurnConfig του Token Extension Program απαιτεί
μια διαμορφωμένη αρχή burn να συν-υπογράφει κάθε burn για το mint.
Ενώ η αρχή burn είναι ορισμένη:
- Οι τυπικές οδηγίες
BurnκαιBurnCheckedαποτυγχάνουν μεTokenError::InvalidInstruction. - Τα burn πρέπει να χρησιμοποιούν
PermissionedBurnInstruction::BurnήPermissionedBurnInstruction::BurnChecked, υπογεγραμμένα τόσο από την αρχή burn όσο και από τον ιδιοκτήτη ή τον εκπρόσωπο του token account.
Η αρχή burn είναι συν-υπογράφων, όχι αντικατάσταση του ιδιοκτήτη. Η αρχή από μόνη της δεν μπορεί να κάνει burn tokens από το token account κάποιου άλλου, και ο ιδιοκτήτης του token account δεν μπορεί να κάνει burn χωρίς την υπογραφή της αρχής. Ένας μόνιμος εκπρόσωπος πρέπει επίσης να χρησιμοποιεί τις οδηγίες permissioned burn και εξακολουθεί να χρειάζεται τη συν-υπογραφή της αρχής burn.
Αυτό επιτρέπει σε έναν εκδότη να διατηρεί την προσφορά token συγχρονισμένη με ένα εκτός αλυσίδας αρχείο, για παράδειγμα ένα tokenized asset που πρέπει να παραμένει υποστηριγμένο σε αναλογία 1:1, αποτρέποντας τους κατόχους από το να κάνουν burn tokens μονομερώς.
Η αρχή burn μπορεί να αντικατασταθεί αργότερα με SetAuthority
χρησιμοποιώντας AuthorityType::PermissionedBurn. Ορίζοντας την αρχή σε
None απενεργοποιεί το permissioned burning και επανενεργοποιεί τις τυπικές
οδηγίες burn. Τα δεδομένα επέκτασης παραμένουν στο mint.
Διαθεσιμότητα
Το Permissioned burn αποστέλλεται στο Token-2022
program@v11.0.0.
Είναι διαθέσιμο στο devnet σήμερα και είναι προγραμματισμένο να ενεργοποιηθεί
στο mainnet τον Ιούνιο του 2026. Το Token Extension Program αναπτύσσεται
ξεχωριστά σε κάθε cluster, οπότε επιβεβαιώστε ότι η ανάπτυξη στο cluster που
στοχεύετε περιλαμβάνει v11.0.0 ή νεότερη έκδοση.
Ένας τοπικός δοκιμαστικός validator περιλαμβάνει επίσης μια παλαιότερη έκδοση του Token-2022, οπότε για να εκτελέσετε τα παραδείγματα αυτής της σελίδας, φορτώστε το πρόγραμμα v11.0.0 από το devnet στον δοκιμαστικό σας validator:
solana program dump -u devnet TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb token_2022.sosolana-test-validator --reset --bpf-program TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb token_2022.so
Πώς να Δημιουργήσετε Mint και Burn με Άδεια
Για να δημιουργήσετε ένα mint με εξουσιοδοτημένο burn και να κάψετε tokens:
- Υπολογίστε το μέγεθος του mint account και το rent που απαιτείται για το mint
και την επέκταση
PermissionedBurnConfig. - Δημιουργήστε το mint account με
CreateAccount, αρχικοποιήστε την επέκτασηPermissionedBurnConfigκαι αρχικοποιήστε το mint μεInitializeMint. - Δημιουργήστε ένα token account και κάντε mint tokens.
- Κάντε burn με
PermissionedBurnInstruction::BurnCheckedυπογεγραμμένο τόσο από τον κάτοχο του token account όσο και από την αρχή έγκρισης burn. - Προαιρετικά, απενεργοποιήστε το εξουσιοδοτημένο burning με
SetAuthorityχρησιμοποιώνταςAuthorityType::PermissionedBurnκαι εξουσίαNone, η οποία επανενεργοποιεί τις τυπικές οδηγίες burn. Τα πλήρη παραδείγματα κώδικα παρακάτω δείχνουν αυτό το βήμα.
Υπολογισμός μεγέθους λογαριασμού
Υπολογίστε το μέγεθος του mint account για το βασικό mint συν την επέκταση
PermissionedBurnConfig. Αυτό είναι το μέγεθος που χρησιμοποιείται στο
CreateAccount.
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 burnAuthority = await generateKeyPairSigner();const permissionedBurnExtension = extension("PermissionedBurn", {authority: burnAuthority.address});const mintSpace = BigInt(getMintSize([permissionedBurnExtension]));
Υπολογισμός rent
Υπολογίστε το rent χρησιμοποιώντας το μέγεθος που απαιτείται για το mint συν την
επέκταση PermissionedBurnConfig.
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 burnAuthority = await generateKeyPairSigner();const permissionedBurnExtension = extension("PermissionedBurn", {authority: burnAuthority.address});const mintSpace = BigInt(getMintSize([permissionedBurnExtension]));const mintRent = await client.rpc.getMinimumBalanceForRentExemption(mintSpace).send();
Δημιουργία του mint account
Δημιουργήστε το mint account με τον υπολογισμένο χώρο και lamports.
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 burnAuthority = await generateKeyPairSigner();const permissionedBurnExtension = extension("PermissionedBurn", {authority: burnAuthority.address});const mintSpace = BigInt(getMintSize([permissionedBurnExtension]));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})]);
Αρχικοποίηση PermissionedBurn
Αρχικοποιήστε την επέκταση PermissionedBurnConfig στο mint με την αρχή
έγκρισης burn.
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 burnAuthority = await generateKeyPairSigner();const permissionedBurnExtension = extension("PermissionedBurn", {authority: burnAuthority.address});const mintSpace = BigInt(getMintSize([permissionedBurnExtension]));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}),getInitializePermissionedBurnInstruction({mint: mint.address,authority: burnAuthority.address})]);
Αρχικοποίηση του mint
Αρχικοποιήστε το mint με InitializeMint στην ίδια συναλλαγή.
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 burnAuthority = await generateKeyPairSigner();const permissionedBurnExtension = extension("PermissionedBurn", {authority: burnAuthority.address});const mintSpace = BigInt(getMintSize([permissionedBurnExtension]));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}),getInitializePermissionedBurnInstruction({mint: mint.address,authority: burnAuthority.address}),getInitializeMintInstruction({mint: mint.address,decimals: 0,mintAuthority: client.payer.address,freezeAuthority: client.payer.address})]);
Δημιουργία token account και κοπή token
Δημιουργήστε ένα token account για τον πληρωτή και κόψτε token σε αυτό.
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 burnAuthority = await generateKeyPairSigner();const permissionedBurnExtension = extension("PermissionedBurn", {authority: burnAuthority.address});const mintSpace = BigInt(getMintSize([permissionedBurnExtension]));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}),getInitializePermissionedBurnInstruction({mint: mint.address,authority: burnAuthority.address}),getInitializeMintInstruction({mint: mint.address,decimals: 0,mintAuthority: client.payer.address,freezeAuthority: client.payer.address})]);const [sourceToken] = 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: sourceToken,mintAuthority: client.payer,amount: 2n,decimals: 0})]);
Καταστροφή με την αρχή καταστροφής
Καταστροφή token με PermissionedBurnInstruction::BurnChecked υπογεγραμμένη
και από τον ιδιοκτήτη του token account και την αρχή καταστροφής.
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 burnAuthority = await generateKeyPairSigner();const permissionedBurnExtension = extension("PermissionedBurn", {authority: burnAuthority.address});const mintSpace = BigInt(getMintSize([permissionedBurnExtension]));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}),getInitializePermissionedBurnInstruction({mint: mint.address,authority: burnAuthority.address}),getInitializeMintInstruction({mint: mint.address,decimals: 0,mintAuthority: client.payer.address,freezeAuthority: client.payer.address})]);const [sourceToken] = 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: sourceToken,mintAuthority: client.payer,amount: 2n,decimals: 0})]);await client.sendTransaction([getPermissionedBurnCheckedInstruction({account: sourceToken,mint: mint.address,permissionedBurnAuthority: burnAuthority,authority: client.payer,amount: 1n,decimals: 0})]);
Σειρά Εντολών
PermissionedBurnInstruction::Initialize πρέπει να έρθει πριν από
InitializeMint. CreateAccount,
PermissionedBurnInstruction::Initialize, και InitializeMint πρέπει
να συμπεριλαμβάνονται στην ίδια συναλλαγή.
Αναφορά Πηγής
| Item | Description | Source |
|---|---|---|
PermissionedBurnConfig | Επέκταση mint που αποθηκεύει την αρχή που απαιτείται για συνυπογραφή κάθε καταστροφής για το mint. | Source |
PermissionedBurnInstruction::Initialize | Εντολή που αρχικοποιεί τη ρύθμιση παραμέτρων permissioned burn πριν από InitializeMint. | Source |
PermissionedBurnInstruction::Burn | Εντολή καταστροφής που απαιτεί υπογραφές από την αρχή καταστροφής και τον ιδιοκτήτη ή εκπρόσωπο του token account. | Source |
PermissionedBurnInstruction::BurnChecked | Εντολή καταστροφής με έλεγχο δεκαδικών που χρησιμοποιεί τους ίδιους λογαριασμούς με PermissionedBurnInstruction::Burn. | Source |
AuthorityType::PermissionedBurn | Διακριτικό αρχής που χρησιμοποιείται με SetAuthority για εναλλαγή ή απενεργοποίηση της αρχής καταστροφής σε ένα mint. | Source |
process_initialize | Λογική επεξεργαστή που αρχικοποιεί PermissionedBurnConfig σε ένα μη αρχικοποιημένο mint και αποθηκεύει την αρχή καταστροφής. | Source |
process_burn | Λογική επεξεργαστή που απορρίπτει τις τυπικές καταστροφές όταν είναι ορισμένη η αρχή καταστροφής και επαληθεύει την υπογραφή της αρχής. | Source |
process_set_authority | Λογική επεξεργαστή που επικυρώνει και εναλλάσσει την αρχή καταστροφής όταν χρησιμοποιείται AuthorityType::PermissionedBurn. | Source |
Typescript
Το παρακάτω παράδειγμα με Kit χρησιμοποιεί απευθείας τις παραγόμενες οδηγίες.
Το δημοσιευμένο πακέτο legacy @solana/spl-token δεν περιλαμβάνει ακόμη
υποστήριξη για permissioned burn, οπότε δεν συμπεριλαμβάνεται αντίστοιχο
παράδειγμα legacy.
Kit
import {lamports,createClient,generateKeyPairSigner,unwrapOption} 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 {AuthorityType,extension,fetchMint,fetchToken,findAssociatedTokenPda,getBurnCheckedInstruction,getCreateAssociatedTokenInstructionAsync,getInitializeMintInstruction,getInitializePermissionedBurnInstruction,getMintSize,getMintToCheckedInstruction,getPermissionedBurnCheckedInstruction,getSetAuthorityInstruction,isExtension,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 burnAuthority = await generateKeyPairSigner();const permissionedBurnExtension = extension("PermissionedBurn", {authority: burnAuthority.address});const mintSpace = BigInt(getMintSize([permissionedBurnExtension]));const mintRent = await client.rpc.getMinimumBalanceForRentExemption(mintSpace).send();await client.sendTransaction([getCreateAccountInstruction({payer: client.payer, // Account funding account creation.newAccount: mint, // New mint account to create.lamports: mintRent, // Lamports funding the mint account rent.space: mintSpace, // Account size in bytes for the mint plus PermissionedBurnConfig.programAddress: TOKEN_2022_PROGRAM_ADDRESS // Program that owns the mint account.}),getInitializePermissionedBurnInstruction({mint: mint.address, // Mint account that stores the PermissionedBurnConfig extension.authority: burnAuthority.address // Authority required to co-sign every burn for the mint.}),getInitializeMintInstruction({mint: mint.address, // Mint account to initialize.decimals: 0, // Number of decimals for the token.mintAuthority: client.payer.address, // Authority allowed to mint new tokens.freezeAuthority: client.payer.address // Authority allowed to freeze token accounts.})]);const [sourceToken] = await findAssociatedTokenPda({mint: mint.address,owner: client.payer.address,tokenProgram: TOKEN_2022_PROGRAM_ADDRESS});await client.sendTransaction([await getCreateAssociatedTokenInstructionAsync({payer: client.payer, // Account funding the associated token account creation.mint: mint.address, // Mint for the associated token account.owner: client.payer.address // Owner of the associated token account.}),getMintToCheckedInstruction({mint: mint.address, // Mint account that issues the tokens.token: sourceToken, // Token account receiving the newly minted tokens.mintAuthority: client.payer, // Signer authorized to mint new tokens.amount: 2n, // Token amount in base units.decimals: 0 // Decimals defined on the mint.})]);let standardBurnFailure: string | undefined;try {await client.sendTransaction([getBurnCheckedInstruction({account: sourceToken, // Token account to burn from.mint: mint.address, // Mint with the permissioned burn configuration.authority: client.payer, // Token account owner signing the burn.amount: 1n, // Token amount in base units.decimals: 0 // Decimals defined on the mint.})]);} catch (error) {standardBurnFailure = error instanceof Error ? error.message : String(error);}if (!standardBurnFailure) {throw new Error("Expected the standard burn to fail");}await client.sendTransaction([getPermissionedBurnCheckedInstruction({account: sourceToken, // Token account to burn from.mint: mint.address, // Mint with the permissioned burn configuration.permissionedBurnAuthority: burnAuthority, // Burn authority co-signing the burn.authority: client.payer, // Token account owner signing the burn.amount: 1n, // Token amount in base units.decimals: 0 // Decimals defined on the mint.})]);await client.sendTransaction([getSetAuthorityInstruction({owned: mint.address, // Mint with the permissioned burn configuration.owner: burnAuthority, // Current burn authority signing the update.authorityType: AuthorityType.PermissionedBurn, // Authority type to update.newAuthority: null // Setting the authority to None disables permissioned burning.})]);await client.sendTransaction([getBurnCheckedInstruction({account: sourceToken, // Token account to burn from.mint: mint.address, // Mint with permissioned burning disabled.authority: client.payer, // Token account owner signing the burn.amount: 1n, // Token amount in base units.decimals: 0 // Decimals defined on the mint.})]);const sourceAccount = await fetchToken(client.rpc, sourceToken);const mintAccount = await fetchMint(client.rpc, mint.address);const permissionedBurnConfig = (unwrapOption(mintAccount.data.extensions) ?? []).find((item) => isExtension("PermissionedBurn", item));console.log("Mint Address:", mint.address);console.log("Error From Failed Standard Burn:", standardBurnFailure);console.log("Source Amount After Burns:", sourceAccount.data.amount);console.log("Extension After Disable:", permissionedBurnConfig);
Rust
use anyhow::{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_associated_token_account_interface::{address::get_associated_token_address_with_program_id,instruction::create_associated_token_account,};use spl_token_2022_interface::{extension::{permissioned_burn::{instruction as permissioned_burn_ix, PermissionedBurnConfig},BaseStateWithExtensions, ExtensionType, StateWithExtensions,},instruction::{burn_checked, initialize_mint, mint_to_checked, set_authority, AuthorityType},state::{Account, 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 burn_authority = 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::PermissionedBurn])?;let mint_rent = client.get_minimum_balance_for_rent_exemption(mint_space).await?;let create_mint_transaction = Transaction::new_signed_with_payer(&[create_account(&fee_payer.pubkey(), // Account funding account creation.&mint.pubkey(), // New mint account to create.mint_rent, // Lamports funding the mint account rent.mint_space as u64, // Account size in bytes for the mint plus PermissionedBurnConfig.&TOKEN_2022_PROGRAM_ID, // Program that owns the mint account.),permissioned_burn_ix::initialize(&TOKEN_2022_PROGRAM_ID, // Token program that owns the mint.&mint.pubkey(), // Mint account that stores the PermissionedBurnConfig extension.&burn_authority.pubkey(), // Authority required to co-sign every burn for the mint.)?,initialize_mint(&TOKEN_2022_PROGRAM_ID, // Program that owns the mint account.&mint.pubkey(), // Mint account to initialize.&fee_payer.pubkey(), // Authority allowed to mint new tokens.Some(&fee_payer.pubkey()), // Authority allowed to freeze token accounts.0, // Number of decimals for the token.)?,],Some(&fee_payer.pubkey()),&[&fee_payer, &mint],client.get_latest_blockhash().await?,);client.send_and_confirm_transaction(&create_mint_transaction).await?;let source_token = get_associated_token_address_with_program_id(&fee_payer.pubkey(),&mint.pubkey(),&TOKEN_2022_PROGRAM_ID,);let create_token_account_transaction = Transaction::new_signed_with_payer(&[create_associated_token_account(&fee_payer.pubkey(), // Account funding the associated token account creation.&fee_payer.pubkey(), // Owner of the associated token account.&mint.pubkey(), // Mint for the associated token account.&TOKEN_2022_PROGRAM_ID, // Token program that owns the token account.),mint_to_checked(&TOKEN_2022_PROGRAM_ID, // Token program that owns the mint and token account.&mint.pubkey(), // Mint account that issues the tokens.&source_token, // Token account receiving the newly minted tokens.&fee_payer.pubkey(), // Signer authorized to mint new tokens.&[&fee_payer.pubkey()], // Additional multisig signers.2, // Token amount in base units.0, // Decimals defined on the mint.)?,],Some(&fee_payer.pubkey()),&[&fee_payer],client.get_latest_blockhash().await?,);client.send_and_confirm_transaction(&create_token_account_transaction).await?;let standard_burn_ix = burn_checked(&TOKEN_2022_PROGRAM_ID, // Token program that processes the burn.&source_token, // Token account to burn from.&mint.pubkey(), // Mint with the permissioned burn configuration.&fee_payer.pubkey(), // Token account owner signing the burn.&[&fee_payer.pubkey()], // Additional multisig signers.1, // Token amount in base units.0, // Decimals defined on the mint.)?;let standard_burn_transaction = Transaction::new_signed_with_payer(&[standard_burn_ix],Some(&fee_payer.pubkey()),&[&fee_payer],client.get_latest_blockhash().await?,);let standard_burn_result = client.simulate_transaction(&standard_burn_transaction).await?;let standard_burn_failure = standard_burn_result.value.err.ok_or_else(|| anyhow!("Expected the standard burn to fail"))?;let permissioned_burn_instruction = permissioned_burn_ix::burn_checked(&TOKEN_2022_PROGRAM_ID, // Token program that processes the burn.&source_token, // Token account to burn from.&mint.pubkey(), // Mint with the permissioned burn configuration.&burn_authority.pubkey(), // Burn authority co-signing the burn.&fee_payer.pubkey(), // Token account owner signing the burn.&[], // Additional multisig signers.1, // Token amount in base units.0, // Decimals defined on the mint.)?;let permissioned_burn_transaction = Transaction::new_signed_with_payer(&[permissioned_burn_instruction],Some(&fee_payer.pubkey()),&[&fee_payer, &burn_authority],client.get_latest_blockhash().await?,);client.send_and_confirm_transaction(&permissioned_burn_transaction).await?;let disable_authority_transaction = Transaction::new_signed_with_payer(&[set_authority(&TOKEN_2022_PROGRAM_ID, // Token program that owns the mint.&mint.pubkey(), // Mint with the permissioned burn configuration.None, // Setting the authority to None disables permissioned burning.AuthorityType::PermissionedBurn, // Authority type to update.&burn_authority.pubkey(), // Current burn authority signing the update.&[], // Additional multisig signers.)?,],Some(&fee_payer.pubkey()),&[&fee_payer, &burn_authority],client.get_latest_blockhash().await?,);client.send_and_confirm_transaction(&disable_authority_transaction).await?;let standard_burn_after_disable_transaction = Transaction::new_signed_with_payer(&[burn_checked(&TOKEN_2022_PROGRAM_ID, // Token program that processes the burn.&source_token, // Token account to burn from.&mint.pubkey(), // Mint with permissioned burning disabled.&fee_payer.pubkey(), // Token account owner signing the burn.&[&fee_payer.pubkey()], // Additional multisig signers.1, // Token amount in base units.0, // Decimals defined on the mint.)?,],Some(&fee_payer.pubkey()),&[&fee_payer],client.get_latest_blockhash().await?,);client.send_and_confirm_transaction(&standard_burn_after_disable_transaction).await?;let source_account = client.get_account(&source_token).await?;let source_state = StateWithExtensions::<Account>::unpack(&source_account.data)?;let mint_account = client.get_account(&mint.pubkey()).await?;let mint_state = StateWithExtensions::<Mint>::unpack(&mint_account.data)?;let permissioned_burn_config = mint_state.get_extension::<PermissionedBurnConfig>()?;println!("Mint Address: {}", mint.pubkey());println!("Error From Failed Standard Burn: {:?}",standard_burn_failure);println!("Source Amount After Burns: {}",u64::from(source_state.base.amount));println!("Extension After Disable: {:?}", permissioned_burn_config);Ok(())}
Is this page helpful?