You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Solana Rust+Anchor框架代币转账测试报错:toString未定义

Solana Anchor代币转账测试报错TypeError: Cannot read property 'toString' of undefined解决方法

问题场景

使用Solana Rust程序结合Anchor框架开发代币转账功能,完成程序编写后执行测试用例时触发以下错误:

Is transfer!:
     TypeError: Cannot read property 'toString' of undefined
      at Transaction.partialSign (node_modules/@solana/web3.js/src/transaction/legacy.ts:642:36)
      at /opt/projects/demo/rust-demo/second/node_modules/@project-serum/anchor/src/provider.ts:142:10
      at Array.forEach (<anonymous>)
      at AnchorProvider.sendAndConfirm (node_modules/@project-serum/anchor/src/provider.ts:141:21)
      at processTicksAndRejections (internal/process/task_queues.js:95:5)
      at MethodsBuilder.rpc [as _rpcFn] (node_modules/@project-serum/anchor/src/program/namespace/rpc.ts:29:16)

涉及代码如下:

Rust程序代码

use anchor_lang::prelude::*;
use anchor_spl::token::{ Token, TokenAccount, Transfer, Mint, self };

pub fn transfer_sol(ctx:Context<TransferInfo>) -> Result<()>{
    let amt: u64 = 1000000;
    msg!("Lamport: {}",amt);
    msg!("Starting Tokens: {}",ctx.accounts.sender.amount);
    let cpi_ctx = CpiContext::new(
        ctx.accounts.token_program.to_account_info(),
        Transfer{
            from:ctx.accounts.sender.to_account_info(),
            to:ctx.accounts.receiver.to_account_info(),
            authority:ctx.accounts.authority.to_account_info(),
        }
    );
    token::transfer(cpi_ctx,amt)?;
    ctx.accounts.sender.reload()?;
    Ok(())
}

#[derive(Accounts)]
pub struct TransferInfo<'info>{
    #[account(mut)]
    pub sender: Box<Account<'info, TokenAccount>>,
    #[account(mut)]
    pub receiver: Box<Account<'info, TokenAccount>>,
    pub authority: Signer<'info>,
    pub mint: Box<Account<'info, Mint>>,
    pub token_program: Program<'info, Token>,
}

测试代码(原错误版本)

it("Is transfer!", async () =>{
      //let amount = new anchor.BN(1000000);
      //let amount = new anchor.web3.BN(LAMPORTS_PER_SOL);
      
      await program.methods.transfera()
        .accounts({
          sender:provider.wallet.publicKey,
          receiver:receiver_token.publicKey,
          authority:provider.wallet.publicKey,
          mint: mint.publicKey,
          tokenProgram:TOKEN_PROGRAM_ID
        })
        .signers([sender_token.publicKey])
        .rpc();

      let tokenbal = await provider.connection.getTokenAccountBalance(sender_token.publicKey);
      console.log("tokenbal ",tokenbal);

      let tokenbalm = await provider.connection.getTokenAccountBalance(receiver_token.publicKey);
      console.log("tokenbalm ",tokenbalm);

  });

错误原因

  1. 方法名不匹配:Rust程序中定义的转账函数是transfer_sol,但测试代码中调用的是transfera(),Anchor无法找到对应方法,导致指令生成异常。
  2. Signers参数错误:signers需要传入签名者的Keypair对象(包含私钥),但代码中传入的是公钥sender_token.publicKey,公钥没有签名所需的私钥属性,触发toString读取undefined的错误。
  3. Accounts参数错误:Rust程序中sender定义为TokenAccount类型,对应代币账户地址,但测试代码中传入的是钱包公钥provider.wallet.publicKey,类型不匹配导致后续流程异常。

修正方案

修正后的测试代码

it("Is transfer!", async () =>{
      // 调用正确的方法名transferSol(Anchor会把snake_case转为camelCase)
      await program.methods.transferSol()
        .accounts({
          // sender替换为代币账户地址
          sender: sender_token.publicKey,
          receiver: receiver_token.publicKey,
          authority: provider.wallet.publicKey,
          mint: mint.publicKey,
          tokenProgram: TOKEN_PROGRAM_ID
        })
        // signers传入钱包的Keypair(authority是钱包,所以用钱包签名)
        .signers([provider.wallet.payer])
        .rpc();

      let tokenbal = await provider.connection.getTokenAccountBalance(sender_token.publicKey);
      console.log("tokenbal ",tokenbal);

      let tokenbalm = await provider.connection.getTokenAccountBalance(receiver_token.publicKey);
      console.log("tokenbalm ",tokenbalm);
  });

额外检查点

  1. 确保执行anchor build生成最新IDL,保证测试代码调用的方法名和IDL中的一致(Anchor会自动将Rust的snake_case函数名转为camelCase,比如transfer_sol对应transferSol)。
  2. 确认sender_token是已初始化的代币账户,且余额足够支付转账金额+手续费。
  3. 确认authority(这里是钱包)是sender代币账户的授权签名者。

内容的提问来源于stack exchange,提问作者Chris Dean

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 10:35:29