【问题标题】:Solana token transfer using Anchor使用 Anchor 进行 Solana 代币转移
【发布时间】:2022-08-13 01:56:59
【问题描述】:

我在做我认为简单的代币转移时遇到了问题。

首先是一些代码:

#[derive(Accounts)]
#[instruction(amount: u64)]
pub struct TransferTokens<\'info> {
    #[account(mut)]
    pub sender: Signer<\'info>,
    #[account(mut)]
    pub sender_tokens: Account<\'info, TokenAccount>,
    pub recipient_tokens: Account<\'info, TokenAccount>,
    pub mint: Account<\'info, Mint>,
    #[account(address = SYSTEM_PROGRAM_ID)]
    pub system_program: Program<\'info, System>,
    #[account(address = TOKEN_PROGRAM_ID)]
    pub token_program: Program<\'info, Token>,
}

pub fn transfer_tokens(ctx: Context<TransferTokens>, amount: u64) -> ProgramResult {
    let sender = &ctx.accounts.sender;
    let sender_tokens = &ctx.accounts.sender_tokens;
    let recipient_tokens = &ctx.accounts.recipient_tokens;
    let token_program = &ctx.accounts.token_program;

    transfer(
        CpiContext::new(
            token_program.to_account_info(),
            Transfer {
                from: sender_tokens.to_account_info(),
                to: recipient_tokens.to_account_info(),
                authority: sender.to_account_info(),
            },
        ),
        amount,
    )?;

    return Ok(());
}
const mint = new PublicKey(\"4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU\"); // USDC devnet
const sender = program.provider.wallet.publicKey;
const recipient = new PublicKey(otherPublicKey);
const senderATA = await getOrCreateAssociatedTokenAccount(...);
const recipientATA = await getOrCreateAssociatedTokenAccount(...);
let instructions: TransactionInstruction[];
if (senderATA.instruction) instructions.push(senderATA.instruction);
if (recipientATA.instruction) instructions.push(recipientATA.instruction);
if (instructions.length === 0) instructions = undefined;
const price = 1000;

await program.rpc.transferTokens(new BN(price), {
  accounts: {
    sender: sender,
    senderTokens: senderATA.address,
    recipientTokens: recipientATA.address,
    mint,
    systemProgram: SystemProgram.programId,
    tokenProgram: TOKEN_PROGRAM_ID
  },
  instructions
});

当我运行它时,我得到:

Transaction simulation failed: Error processing Instruction 0: Cross-program invocation with unauthorized signer or writable account 
    Program XXX invoke [1]
    recipientATA.address\'s writable privilege escalated
    Program XXX consumed 9908 of 200000 compute units
    Program XXX failed: Cross-program invocation with unauthorized signer or writable account

显然发件人必须签署交易,但我想我真的不明白为什么我需要许可才能将令牌发送给其他人。

JS 代码略有缩写,但我正在做的是添加指令以创建令牌帐户,除非它们存在。奇怪的是,这在我第一次包含创建令牌帐户的说明时有效,但之后发生了“可写权限升级”错误。

谁能看到我做错了什么?

    标签: solana anchor-solana


    【解决方案1】:

    当您将代币从一个用户转移到另一个用户时,TokenAccounts 都必须标记为可变的,因为在幕后您是从一个用户的金额中减去并添加到另一个用户的金额!

    换句话说,您需要将#[account(mut)] 添加到接收令牌帐户和与之关联的铸币厂。

    #[account(mut)]
    pub recipient_tokens: Account<'info, TokenAccount>,
    
    // ...
    
    #[account(mut)]
    pub mint: Account<'info, Mint>,
    

    【讨论】:

      【解决方案2】:

      发送者和接收者都需要是 mut (可写),因为令牌程序需要改变他们的余额。

      mint 帐户可以完全省略,因为令牌程序只是确保两个帐户来自同一个 mint pubkey。在转移过程中,任何东西都不需要铸币帐户中包含的实际数据。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-10-13
        • 2023-02-03
        • 2021-11-07
        • 2022-06-20
        • 2018-07-02
        • 2023-02-22
        • 2022-11-14
        • 1970-01-01
        相关资源
        最近更新 更多