批准委托

批准委托有什么作用?

批准委托允许另一个地址代表代币账户所有者从 token account 转移或销毁有限数量的代币。

一个 token account 一次只能存储一个当前委托和一个委托金额。批准新委托将替换账户上的先前委托和额度。

如何批准委托

批准委托使用 Token Program 的 ApproveApproveChecked 指令。

以下示例使用 ApproveChecked,它要求调用者提供铸币地址和小数位数,以便指令在处理批准之前验证预期的铸币地址和代币精度。

代币账户所有者签署批准。

源代码参考

项目描述Token ProgramToken Extensions Program
Account代币账户状态存储所有者、委托和委托金额。源代码源代码
Approve委托批准指令,记录代币账户的委托和额度,无需调用者提供铸币地址或小数位数。源代码源代码
ApproveChecked委托批准指令,要求调用者提供铸币地址和小数位数,并在记录委托和额度之前检查这些值。源代码源代码
process_approve委托批准的共享处理器逻辑。源代码源代码

Typescript

以下 Kit 示例展示了使用 @solana/kit 的推荐方法。使用 @solana/web3.js 的旧版示例仅供参考。

Kit

import { generateKeyPairSigner } from "@solana/kit";
import { createLocalClient } from "@solana/kit-client-rpc";
import {
findAssociatedTokenPda,
tokenProgram,
TOKEN_PROGRAM_ADDRESS
} from "@solana-program/token";
const client = await createLocalClient()
.use(tokenProgram());
const mint = await generateKeyPairSigner();
const delegate = await generateKeyPairSigner();
const [tokenAccount] = await findAssociatedTokenPda({
mint: mint.address,
owner: client.payer.address,
tokenProgram: TOKEN_PROGRAM_ADDRESS
});
const result = await client.token.instructions
.approveChecked({
source: tokenAccount, // Token account whose delegate approval changes.
mint: mint.address, // Mint for the token the delegate may spend.
delegate: delegate.address, // Delegate allowed to spend from the token account.
owner: client.payer, // Owner approving this delegate change.
amount: 25n, // Token amount in base units.
decimals: 2 // Decimals defined on the mint account.
})
.sendTransaction();
const tokenAccountData = await client.token.accounts.token.fetch(tokenAccount);
console.log("Mint Address:", mint.address);
console.log("\nToken Account Address:", tokenAccount);
console.log("Token Account:", tokenAccountData.data);
console.log("\nDelegate Address:", delegate.address);
console.log("\nTransaction Signature:", result.context.signature);
Console
Click to execute the code.

Web3.js

import { Connection, Keypair, LAMPORTS_PER_SOL } from "@solana/web3.js";
import {
createAssociatedTokenAccount,
approveChecked,
createMint,
getAccount,
mintToChecked,
TOKEN_PROGRAM_ID
} from "@solana/spl-token";
const result = await approveChecked(
connection, // Connection to the local validator.
feePayer, // Account paying transaction fees.
mintPubkey, // Mint for the token the delegate may spend.
associatedTokenAccount, // Token account whose delegate approval changes.
delegate.publicKey, // Delegate allowed to spend from the token account.
feePayer, // Owner approving this delegate change.
25, // Token amount in base units.
2, // Decimals defined on the mint account.
[], // Additional multisig signers.
{
commitment: "confirmed" // Confirmation options for the transaction.
},
TOKEN_PROGRAM_ID // Token program to invoke.
);
const tokenAccountData = await getAccount(
connection,
associatedTokenAccount,
"confirmed",
TOKEN_PROGRAM_ID
);
console.log("Mint Address:", mintPubkey.toBase58());
console.log(
"\nAssociated Token Account Address:",
associatedTokenAccount.toBase58()
);
console.log("Associated Token Account:", tokenAccountData);
console.log("\nDelegate Address:", delegate.publicKey.toBase58());
console.log("\nTransaction Signature:", result);
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::{
program_pack::Pack,
signature::{Keypair, Signer},
transaction::Transaction,
};
use solana_system_interface::instruction::create_account;
use spl_associated_token_account_interface::{
address::get_associated_token_address, instruction::create_associated_token_account,
};
use spl_token_interface::{
id as token_program_id,
instruction::{approve_checked, initialize_mint, mint_to_checked},
state::{Account, Mint},
};
#[tokio::main]
async fn main() -> Result<()> {
let client = RpcClient::new_with_commitment(
String::from("http://localhost:8899"),
CommitmentConfig::confirmed(),
);
let delegate = Keypair::new();
let approve_amount = 25;
let transaction = Transaction::new_signed_with_payer(
&[
approve_checked(
&token_program_id(), // Token program to invoke.
&associated_token_address, // Token account whose delegate approval changes.
&mint.pubkey(), // Mint for the token the delegate may spend.
&delegate.pubkey(), // Delegate allowed to spend from the token account.
&fee_payer.pubkey(), // Owner approving this delegate change.
&[], // Additional multisig signers.
approve_amount, // Token amount in base units.
decimals, // Decimals defined on the mint account.
)?,
],
Some(&fee_payer.pubkey()),
&[&fee_payer],
latest_blockhash,
);
let transaction_signature = client.send_and_confirm_transaction(&transaction).await?;
let token_account = client.get_account(&associated_token_address).await?;
let token_data = Account::unpack(&token_account.data)?;
println!("Mint Address: {}", mint.pubkey());
println!(
"\nAssociated Token Account Address: {}",
associated_token_address
);
println!("Associated Token Account: {:#?}", token_data);
println!("\nDelegate Address: {}", delegate.pubkey());
println!("\nTransaction Signature: {}", transaction_signature);
Ok(())
}
Console
Click to execute the code.

Python

Python
#!/usr/bin/env python3
import asyncio
import json
from solana.rpc.async_api import AsyncClient
from solders.keypair import Keypair
from solders.message import Message
from solders.pubkey import Pubkey
from solders.system_program import create_account, CreateAccountParams
from solders.transaction import Transaction
from spl.token.async_client import AsyncToken
from spl.token.instructions import (
approve_checked,
ApproveCheckedParams,
create_associated_token_account,
get_associated_token_address,
initialize_mint,
InitializeMintParams,
mint_to_checked,
MintToCheckedParams,
)
from spl.token.constants import MINT_LEN, TOKEN_PROGRAM_ID
DECIMALS = 2
AMOUNT_TO_MINT = 100
AMOUNT_TO_APPROVE = 25
async def main():
rpc = AsyncClient("http://localhost:8899")
delegate = Keypair()
async with rpc:
approve_delegate_instruction = approve_checked(
ApproveCheckedParams(
program_id=TOKEN_PROGRAM_ID, # Token program to invoke.
source=token_account_address, # Token account whose delegate approval changes.
mint=mint.pubkey(), # Mint for the token the delegate may spend.
delegate=delegate.pubkey(), # Account allowed to spend from the token account.
owner=fee_payer.pubkey(), # Account that owns the token account.
amount=AMOUNT_TO_APPROVE, # Token amount in base units.
decimals=DECIMALS, # Decimals defined on the mint account.
)
)
latest_blockhash = await rpc.get_latest_blockhash()
transaction = Transaction(
[fee_payer],
Message([approve_delegate_instruction], fee_payer.pubkey()),
latest_blockhash.value.blockhash,
)
result = await rpc.send_transaction(transaction)
token_account_info = await token.get_account_info(token_account_address)
token_account = {
key: str(value) if isinstance(value, Pubkey) else value
for key, value in token_account_info._asdict().items()
}
print("Mint Address:", mint.pubkey())
print("\nToken Account Address:", token_account_address)
print("Token Account:")
print(json.dumps(token_account, indent=2))
print("\nDelegate Address:", delegate.pubkey())
print("\nTransaction Signature:", result.value)
if __name__ == "__main__":
asyncio.run(main())
Console
Click to execute the code.

Is this page helpful?

Table of Contents

Edit Page

管理者

©️ 2026 Solana 基金会版权所有
取得联系