Solana Anchor Rust中如何将Pubkey转换为AccountInfo类型
核心结论
你无法直接将Pubkey类型转换为AccountInfo类型。AccountInfo是Solana运行时加载到程序执行上下文中的账户状态封装,仅包含公钥的情况下你不可能拿到链上账户的lamports、存储数据、租期等真实状态,手动构造AccountInfo的方案完全不可行,就算你强行赋值也会触发链上运行时的校验错误。
正确实现方案
所有你程序需要访问的账户必须提前在指令的Accounts结构体中声明,额外新增用户代币账户字段,同时加约束校验该账户地址与你存储在用户存储账户中的公钥一致即可:
#[derive(Accounts)] pub struct Stake<'info> { // 你原有的用户存储账户 pub user_acct: Account<'info, UserAcct>, // 新增用户奖励代币账户字段,用has_one约束校验地址匹配 #[account( has_one = reward_user @ YourCustomError::InvalidRewardTokenAccount, )] pub user_reward_token_account: InterfaceAccount<'info, TokenAccount>, // 你原有的其他账户 pub reward_mint: InterfaceAccount<'info, Mint>, pub pg_signer: Signer<'info>, pub token_program: Interface<'info, TokenInterface>, // ... 其他账户省略 }
上述has_one约束会自动校验user_reward_token_account.key()与user_acct.reward_user是否相等,不等就会直接返回自定义错误,不需要你手动写判断逻辑。
之后你构造MintTo CPI的时候直接使用这个已声明的账户即可:
let cpi_accounts = MintTo { mint: ctx.accounts.reward_mint.to_account_info(), to: ctx.accounts.user_reward_token_account.to_account_info(), authority: ctx.accounts.pg_signer.to_account_info() }; let cpi_ctx = CpiContext::new(ctx.accounts.token_program.to_account_info(), cpi_accounts); token::mint_to(cpi_ctx, 奖励数量)?;
补充说明
Solana程序只能访问交易调用方主动传入的账户列表内的账户,未在交易中传入的账户程序没有任何权限读取其状态,不要尝试绕过Accounts结构体声明的规则直接构造账户实例,这会带来严重的安全漏洞,也无法通过运行时校验。
内容的提问来源于stack exchange,提问作者Russo
相关产品推荐
相关产品推荐

