Solana Anchor Rust:如何将公钥转换为AccountInfo类型

12

我知道可以通过上下文结构(Context struct)像Anchor教程2中所示,给我的Solana Rust程序提供用户的令牌账户:

https://project-serum.github.io/anchor/tutorials/tutorial-2.html#defining-a-program

#[derive(Accounts)]
pub struct Stake<'info> {
  pub user_reward_token_account: CpiAccount<'info, TokenAccount>,
  ...
}

但是如果我想让用户先将该用户的令牌账户保存在特定用户的存储账户中,然后让我的 Solana 程序从该用户的存储账户获取这些令牌账户呢?

let user_acct = &ctx.accounts.user_acct;

当尝试将一些奖励代币铸造到用户的代币账户时:

let cpi_accounts = MintTo {
  mint: ctx.accounts.reward_mint.to_account_info(),
  to: user_acct.reward_user,
  authority: ctx.accounts.pg_signer.clone()
};

在编译时出现了错误:期望结构体 anchor_lang::prelude::AccountInfo,但找到结构体 anchor_lang::prelude::Pubkey

但在 anchor_lang::prelude::Pubkey 中找不到 to_account_info() 方法。

我检查了 Pubkey 文档:https://docs.rs/anchor-lang/0.13.2/anchor_lang/prelude/struct.Pubkey.html

但它没有提到 AccountInfo......

然后我尝试使用 https://docs.rs/anchor-lang/0.13.2/anchor_lang/prelude/struct.AccountInfo.html 中的方法从 reward_user 地址创建一个 AccountInfo 结构体:

let to_addr = AccountInfo {
  key: &user_acct.reward_user,
  is_signer: false,
  is_writable: true,
  lamports: Rc<RefCell<&'a mut u64>>,
  data: Rc<RefCell<&'a mut [u8]>>,
  owner: &user_pda.user_acct,
  executable: false,
  rent_epoch: u64,
};

但这真的很困难,而且我不知道Lamports、数据和Rent_Epoch值是什么...

那么我该如何将公钥转换为AccountInfo类型?

2个回答

5

为了能够访问其数据,您需要通过上下文传递帐户。这种设计使Solana能够在运行时之前知道需要哪些帐户和数据,从而更好地并行处理交易。


1
我该怎么做? - att
1
我们可以请您提供关于此事更多的信息吗?这并不是很有帮助。 - Julia
质押示例在此处 - https://github.com/paramsNFT/nft_staking - wxecqz123
1
但是如果账户地址不存在且是在链上生成的呢? - mega_creamery

3
为了让Sealevel并行处理一批指令,即使该账户尚不存在,您也需要在要被程序使用的账户列表中提供一个账户。因为正在创建一个账户时,它需要有一些lamports转移到其中以免租金。存入lamports将需要修改此账户的状态,因此需要将其标记为可写。
我遇到了一个潜在但不太可能发生的并发问题,PDA种子会包含另一个账户的状态,然后会增加这个账户的计数器。这是Solana的一种方法,用于处理没有大小限制且可以索引或循环的数组。我希望每次调用都能在链上组装一个新的账户地址,而不是依靠两个客户端不读取计数器状态,但其中一个提交的交易略慢,并被拒绝。这是不可能的。
实际上,这意味着客户端总是必须派生PDA并将其传递给程序,即使程序本身将再次执行相同的操作,然后将事务提交给系统程序。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接