Solana合约lending_pool账户未生成,测试报TypeError求助
解决Solana借贷合约测试中
program.account.lendingPool未定义的错误 问题概述
运行Solana借贷合约测试脚本时触发错误:TypeError: Cannot read properties of undefined (reading 'fetch'),排查发现program.account对象为空,lending_pool账户未成功生成,无法正常获取该账户数据。
错误原因分析
- Anchor类型生成不完整:Rust合约代码的结构问题导致TypeScript类型未正确生成,
program.account下缺少lendingPool属性。 - 账户空间分配不足:
LendingPool结构体包含多个动态数组,固定分配的空间不足以存储数据,导致账户初始化静默失败。 - PDA验证参数缺失:测试中未传递PDA生成的
bump值,导致合约无法验证PDA合法性,初始化逻辑未执行完成。
修复步骤
一、修正合约代码
1. 调整结构体定义顺序
将Borrower结构体移至LendingPool之前,避免编译时的引用顺序问题:
// Borrower struct to track borrowed amounts and collateral #[derive(AnchorSerialize, AnchorDeserialize, Clone, Copy)] pub struct Borrower { pub amount_borrowed: u64, pub collateral_amount: u64, pub collateral_token: Pubkey, pub has_repaid: bool, } #[account] pub struct LendingPool { pub is_initialized: bool, pub pool_token_account: Pubkey, pub lenders: Vec<(Pubkey, Pubkey, u64)>, // lender -> token -> amountLent pub borrowers: Vec<(Pubkey, Pubkey, Borrower)>, // borrower -> token -> Borrower pub total_lending_pool: Vec<(Pubkey, u64)>, // token -> amount in pool pub borrow_tokens: Vec<Pubkey>, // List of borrow tokens pub collateral_tokens: Vec<Pubkey>, // List of collateral tokens }
2. 修正账户空间分配
为LendingPool分配足够的动态空间,替换原固定值:
#[derive(Accounts)] pub struct Initialize<'info> { // 按结构体字段计算足够空间,适配动态数组增长 #[account(init, payer = admin, seeds = [b"lending_pool"], bump, space = 8 + 32 + 4 + (32+32+8)*100 + 4 + (32+32+32+8+1)*100 + 4 + (32+8)*100 + 4 + 32*100 + 4 + 32*100)] pub lending_pool: Account<'info, LendingPool>, #[account(mut)] pub admin: Signer<'info>, pub system_program: Program<'info, System>, }
3. 重新生成TypeScript类型
执行命令更新类型定义:
anchor build anchor typescript
二、修正测试代码
1. 传递PDA bump参数
初始化指令需验证PDA合法性,测试中需传递生成的bump值:
// Create and initialize the lending pool await program.rpc.initialize( [], // Empty borrow_tokens array for simplicity [], // Empty collateral_tokens array for simplicity poolTokenAccount.publicKey, { accounts: { lendingPool: lendingPoolPda, admin: admin.publicKey, systemProgram: anchor.web3.SystemProgram.programId, }, signers: [admin], // 传递PDA验证所需的bump值 seeds: [[Buffer.from("lending_pool"), [bump]]], } );
2. 确保Airdrop完成
添加确认逻辑,保证admin账户获得足够SOL:
// Airdrop some SOL to the admin to pay for transactions const airdropTx = await provider.connection.requestAirdrop(admin.publicKey, anchor.web3.LAMPORTS_PER_SOL); await provider.connection.confirmTransaction({ signature: airdropTx, commitment: "confirmed" });
3. 安全获取账户数据
使用tryFetch避免直接报错,同时验证账户存在:
// Fetch the lending pool account const lendingPoolAccount = await program.account.lendingPool.tryFetch(lendingPoolPda); if (!lendingPoolAccount) { throw new Error("Lending pool account not initialized"); } console.log("Lending pool account fetched:", lendingPoolAccount);
验证修复
- 重新编译合约:
anchor build - 部署到本地节点:
anchor deploy - 运行测试:
anchor test
内容的提问来源于stack exchange,提问作者Valido
相关产品推荐
相关产品推荐

