Aseta valtuus
Token-valtuuksien ymmärtäminen
Mint account -valtuudet
- Mint-valtuus: Hallinnoi uusien tokenien luomista. Voi mintata tokeneita mihin tahansa token account -tilille. Usein peruutetaan alkuperäisen tarjonnan luomisen jälkeen kiinteän tarjonnan tokenin luomiseksi.
- Jäädytysvaltuus: Hallinnoi kykyä jäädyttää ja sulattaa token account -tilejä. Voi estää minkä tahansa token account -tilin siirtämästä tokeneita. Usein peruutetaan takaamaan käyttäjille, että heidän tokeneitaan ei voida jäädyttää.
Token account -valtuudet
- Tilin omistaja: Hallinnoi täysin token account -tiliä. Voi siirtää tokeneita, polttaa tokeneita, hyväksyä valtuutettuja ja sulkea tilin, kun saldo on nolla.
- Sulkemisvaltuus: Voi sulkea token account -tilin, kun sen saldo on nolla. Oletuksena tämä on tilin omistaja, mutta se voidaan delegoida toiselle tilille.
Miten asettaa valtuus
SetAuthority
-ohje muuttaa tai peruuttaa valtuuksia mint- ja token account -tileillä. Vain
nykyinen valtuutettu voi siirtää oikeutensa uuteen osoitteeseen tai peruuttaa ne
pysyvästi asettamalla valtuuden null-arvoksi. Kun valtuus on peruutettu, sitä ei
voida palauttaa.
Token Program ja Token Extensions Program jakavat samankaltaiset toteutukset saavuttaakseen saman toiminnallisuuden.
Typescript
import {airdropFactory,appendTransactionMessageInstructions,createSolanaRpc,createSolanaRpcSubscriptions,createTransactionMessage,generateKeyPairSigner,getSignatureFromTransaction,lamports,pipe,sendAndConfirmTransactionFactory,setTransactionMessageFeePayerSigner,setTransactionMessageLifetimeUsingBlockhash,signTransactionMessageWithSigners} from "@solana/kit";import { getCreateAccountInstruction } from "@solana-program/system";import {getInitializeMintInstruction,getMintSize,TOKEN_PROGRAM_ADDRESS,findAssociatedTokenPda,getCreateAssociatedTokenInstructionAsync,getSetAuthorityInstruction,AuthorityType} from "@solana-program/token";// Create Connection, local validator in this exampleconst rpc = createSolanaRpc("http://localhost:8899");const rpcSubscriptions = createSolanaRpcSubscriptions("ws://localhost:8900");// Generate keypairs for fee payer and new authorityconst feePayer = await generateKeyPairSigner();const newAuthority = await generateKeyPairSigner();// Fund fee payerawait airdropFactory({ rpc, rpcSubscriptions })({recipientAddress: feePayer.address,lamports: lamports(1_000_000_000n),commitment: "confirmed"});// Generate keypair to use as address of mintconst mint = await generateKeyPairSigner();// Get default mint account size (in bytes), no extensions enabledconst space = BigInt(getMintSize());// Get minimum balance for rent exemptionconst rent = await rpc.getMinimumBalanceForRentExemption(space).send();// Get latest blockhash to include in transactionconst { value: latestBlockhash } = await rpc.getLatestBlockhash().send();// Instruction to create new account for mint (token program)// Invokes the system programconst createAccountInstruction = getCreateAccountInstruction({payer: feePayer,newAccount: mint,lamports: rent,space,programAddress: TOKEN_PROGRAM_ADDRESS});// Instruction to initialize mint account data// Invokes the token programconst initializeMintInstruction = getInitializeMintInstruction({mint: mint.address,decimals: 9,mintAuthority: feePayer.address,freezeAuthority: feePayer.address});// Use findAssociatedTokenPda to derive the ATA addressconst [associatedTokenAddress] = await findAssociatedTokenPda({mint: mint.address,owner: feePayer.address,tokenProgram: TOKEN_PROGRAM_ADDRESS});// Create instruction to create the associated token accountconst createAtaInstruction = await getCreateAssociatedTokenInstructionAsync({payer: feePayer,mint: mint.address,owner: feePayer.address});const instructions = [createAccountInstruction,initializeMintInstruction,createAtaInstruction];// Create transaction messageconst transactionMessage = pipe(createTransactionMessage({ version: 0 }),(tx) => setTransactionMessageFeePayerSigner(feePayer, tx),(tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),(tx) => appendTransactionMessageInstructions(instructions, tx));// Sign transaction message with all required signersconst signedTransaction =await signTransactionMessageWithSigners(transactionMessage);// Send and confirm transactionawait sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions })(signedTransaction,{ commitment: "confirmed" });// Get transaction signatureconst transactionSignature = getSignatureFromTransaction(signedTransaction);console.log("\nMint Address:", mint.address.toString());console.log("New Authority Address:", newAuthority.address.toString());console.log("Associated Token Account Address:",associatedTokenAddress.toString());console.log("\nTransaction Signature:", transactionSignature);// Get a fresh blockhash for the authority change transactionconst { value: authorityBlockhash } = await rpc.getLatestBlockhash().send();// 1. Change Mint Authority (MintTokens)const setMintAuthorityIx = getSetAuthorityInstruction({owned: mint.address,owner: feePayer,authorityType: AuthorityType.MintTokens,newAuthority: newAuthority.address});// 2. Change Freeze Authority (FreezeAccount)const setFreezeAuthorityIx = getSetAuthorityInstruction({owned: mint.address,owner: feePayer,authorityType: AuthorityType.FreezeAccount,newAuthority: newAuthority.address});// Create transaction message for authority changesconst authorityTxMessage = pipe(createTransactionMessage({ version: 0 }),(tx) => setTransactionMessageFeePayerSigner(feePayer, tx),(tx) => setTransactionMessageLifetimeUsingBlockhash(authorityBlockhash, tx),(tx) =>appendTransactionMessageInstructions([setMintAuthorityIx, setFreezeAuthorityIx],tx));// Sign transaction message with all required signersconst signedAuthorityTx =await signTransactionMessageWithSigners(authorityTxMessage);// Send and confirm transactionawait sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions })(signedAuthorityTx,{ commitment: "confirmed" });// Get transaction signatureconst transactionSignature2 = getSignatureFromTransaction(signedAuthorityTx);console.log("\nSuccessfully changed mint and freeze authorities");console.log("Transaction Signature:", transactionSignature2);// Get a fresh blockhash for the revoke transactionconst { value: revokeBlockhash } = await rpc.getLatestBlockhash().send();// 3. Example of revoking authority (setting to null)const revokeMintAuthorityIx = getSetAuthorityInstruction({owned: mint.address,owner: newAuthority,authorityType: AuthorityType.MintTokens,newAuthority: null});// Create transaction message for revokingconst revokeTxMessage = pipe(createTransactionMessage({ version: 0 }),(tx) => setTransactionMessageFeePayerSigner(feePayer, tx),(tx) => setTransactionMessageLifetimeUsingBlockhash(revokeBlockhash, tx),(tx) => appendTransactionMessageInstructions([revokeMintAuthorityIx], tx));// Sign transaction message with all required signers (newAuthority needs to sign)const signedRevokeTx = await signTransactionMessageWithSigners(revokeTxMessage);// Send and confirm transactionawait sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions })(signedRevokeTx,{ commitment: "confirmed" });// Get transaction signatureconst transactionSignature3 = getSignatureFromTransaction(signedRevokeTx);console.log("\nSuccessfully revoked mint authority");console.log("Transaction Signature:", transactionSignature3);
Console
Click to execute the code.
Rust
use anyhow::Result;use solana_client::nonblocking::rpc_client::RpcClient;use solana_sdk::{commitment_config::CommitmentConfig,program_pack::Pack,signature::{Keypair, Signer},system_instruction::create_account,transaction::Transaction,};use spl_associated_token_account::{get_associated_token_address_with_program_id, instruction::create_associated_token_account,};use spl_token::{id as token_program_id,instruction::{initialize_mint, set_authority, AuthorityType},state::Mint,};#[tokio::main]async fn main() -> Result<()> {// Create connection to local validatorlet client = RpcClient::new_with_commitment(String::from("http://localhost:8899"),CommitmentConfig::confirmed(),);let latestBlockhash = client.get_latest_blockhash().await?;// Generate a new keypair for the fee payerlet fee_payer = Keypair::new();// Generate a new keypair for the new authoritylet new_authority = Keypair::new();// Airdrop 1 SOL to fee payerlet airdrop_signature = client.request_airdrop(&fee_payer.pubkey(), 1_000_000_000).await?;client.confirm_transaction(&airdrop_signature).await?;loop {let confirmed = client.confirm_transaction(&airdrop_signature).await?;if confirmed {break;}}// Generate keypair to use as address of mintlet mint = Keypair::new();// Get default mint account size (in bytes), no extensions enabledlet mint_space = Mint::LEN;let mint_rent = client.get_minimum_balance_for_rent_exemption(mint_space).await?;// Instruction to create new account for mint (token program)let create_account_instruction = create_account(&fee_payer.pubkey(), // payer&mint.pubkey(), // new account (mint)mint_rent, // lamportsmint_space as u64, // space&token_program_id(), // program id);// Instruction to initialize mint account datalet initialize_mint_instruction = initialize_mint(&token_program_id(),&mint.pubkey(), // mint&fee_payer.pubkey(), // mint authoritySome(&fee_payer.pubkey()), // freeze authority9, // decimals)?;// Calculate the associated token account address for fee_payerlet associated_token_address = get_associated_token_address_with_program_id(&fee_payer.pubkey(), // owner&mint.pubkey(), // mint&token_program_id(), // program_id);// Instruction to create associated token accountlet create_ata_instruction = create_associated_token_account(&fee_payer.pubkey(), // funding address&fee_payer.pubkey(), // wallet address&mint.pubkey(), // mint address&token_program_id(), // program id);// Create transaction and add instructionslet transaction = Transaction::new_signed_with_payer(&[create_account_instruction,initialize_mint_instruction,create_ata_instruction,],Some(&fee_payer.pubkey()),&[&fee_payer, &mint],latestBlockhash,);// Send and confirm transactionlet transaction_signature = client.send_and_confirm_transaction(&transaction).await?;println!("Mint Address: {}", mint.pubkey());println!("New Authority Address: {}", new_authority.pubkey());println!("Associated Token Account Address: {}",associated_token_address);println!("Transaction Signature: {}", transaction_signature);// Get the latest blockhash for the authority change transactionlet latestBlockhash = client.get_latest_blockhash().await?;// 1. Change Mint Authority (MintTokens)let set_mint_authority_ix = set_authority(&token_program_id(), // program id&mint.pubkey(), // mint accountSome(&new_authority.pubkey()), // new authorityAuthorityType::MintTokens, // authority type&fee_payer.pubkey(), // current authority&[&fee_payer.pubkey()], // signers)?;// 2. Change Freeze Authority (FreezeAccount)let set_freeze_authority_ix = set_authority(&token_program_id(), // program id&mint.pubkey(), // mint accountSome(&new_authority.pubkey()), // new authorityAuthorityType::FreezeAccount, // authority type&fee_payer.pubkey(), // current authority&[&fee_payer.pubkey()], // signers)?;// Create transaction for authority changeslet transaction = Transaction::new_signed_with_payer(&[set_mint_authority_ix, set_freeze_authority_ix],Some(&fee_payer.pubkey()),&[&fee_payer],latestBlockhash,);// Send and confirm transactionlet transaction_signature = client.send_and_confirm_transaction(&transaction).await?;println!("\nSuccessfully changed mint and freeze authorities to: {}",new_authority.pubkey());println!("Transaction Signature: {}", transaction_signature);// Get the latest blockhash for the revoke transactionlet latestBlockhash = client.get_latest_blockhash().await?;// 3. Example of revoking authority (setting to null)let revoke_mint_authority_ix = set_authority(&token_program_id(), // program id&mint.pubkey(), // mint accountNone, // new authority (None to revoke)AuthorityType::MintTokens, // authority type&new_authority.pubkey(), // current authority&[&new_authority.pubkey()], // signers)?;// Create transaction for revokinglet transaction = Transaction::new_signed_with_payer(&[revoke_mint_authority_ix],Some(&fee_payer.pubkey()),&[&fee_payer, &new_authority], // new_authority needs to signlatestBlockhash,);// Send and confirm transactionlet transaction_signature = client.send_and_confirm_transaction(&transaction).await?;println!("\nSuccessfully revoked mint authority");println!("Transaction Signature: {}", transaction_signature);Ok(())}
Console
Click to execute the code.
Is this page helpful?