gpt4 book ai didi

rust - 如何将 SOL 从创建 token 关联帐户的 PDA 转移到 Anchor 中的普通帐户?

转载 作者:行者123 更新时间:2023-12-05 04:31:13 30 4
gpt4 key购买 nike

如果一个 PDA 被创建为关联 token 地址,它不能将 SOL 从 PDA 转移到另一个帐户吗?

我想使用一个 PDA 帐户同时转移 SOL 和 SPL-Token。

我尝试了 solana_program::program::invoke_signedsystem_instruction::transfer 以及 try_borrow_mut_lamports()。但是,它不起作用。

Whenever transfer with system_program, I got Transfer: from must not carry data, 另一种方式是instruction spent from a account it does not拥有

我错过了什么?

我能得到一些建议吗?

谢谢。

Struct 中的关联 token 帐户

#[account(init, 
seeds = [authority.to_account_info().key.as_ref()],
bump,
payer = authority,
token::mint = mint,
token::authority = authority)
]
pub vault: Account<'info, TokenAccount>,

创建另一个PDA,从保险库账户转移spl-token时的权限

let (vault_authority, vault_authority_bump) = Pubkey::find_program_address(
&[ctx.accounts.vault.to_account_info().key.as_ref()], ctx.program_id
);

let cpi_accounts = SetAuthority {
account_or_mint: ctx.accounts.vault.to_account_info().clone(),
current_authority: ctx.accounts.authority.to_account_info().clone()
};
let cpi_context = CpiContext::new(ctx.accounts.token_program.to_account_info().clone(), cpi_accounts);
token::set_authority(cpi_context, AuthorityType::AccountOwner, Some(vault_authority))?;

失败案例 1,使用 system_program 将 SOL 从金库转移到所有者

// Error message : Transfer: `from` must not carry data
let vault_key = ctx.accounts.authority.to_account_info().key.as_ref();
let (_vault, bump) = Pubkey::find_program_address(&[vault_key], ctx.program_id);
let seeds = &[vault_key, &[bump]];
let signer = &[&seeds[..]];

let owner_key = &ctx.accounts.owner.key();
let vault_key = &ctx.accounts.vault.key();
let ix = system_instruction::transfer(vault_key, owner_key, amount);

let owner_account = ctx.accounts.owner.to_account_info();
let vault_account = ctx.accounts.vault.to_account_info();
solana_program::program::invoke_signed(&ix, &[vault_account, owner_account], signer)?;

失败案例 2,使用“try_borrow_mut_lamports”将 SOL 从保险库转移到所有者

// Error message : instruction spent from the balance of an account it does not own
**ctx.accounts.vault.to_account_info().try_borrow_mut_lamports()? -= amount;
**ctx.accounts.owner.to_account_info().try_borrow_mut_lamports()? += amount;

最佳答案

无法从同一个帐户转移 SOL 和 SPL 代币。 SPL 代币账户(关联或非关联)归 SPL 代币程序所有,这意味着只有 SPL 代币程序可以更改其数据并扣除其 lamports。否则,任何人都有可能将代币账户置于免租和违背代币计划的保证之下。

让我们通过您的案例并解释它们为何不起作用:

  • 失败案例 1,使用 system_program 触发将 SOL 从金库转移到所有者:Transfer: from must not carry data

这里实际上有两个错误,但只报告了第一个。当您尝试从 vault 中 system_instruction::transfer 时,它主要会失败,因为 vault 不属于系统程序。它归 token 程序所有,因此只有 token 程序可以移动它的 lamports,而系统程序不能。报告的失败表明该帐户也有数据,即 token 数据(所有者、数量、委托(delegate)等)。

  • 失败案例 2,使用“try_borrow_mut_lamports”将 SOL 从金库转移到所有者

这个非常相似——不是系统程序试图从 token 帐户中扣除 lamports,而是您的程序试图这样做,因此运行时将再次说“这是不允许的”。

关于rust - 如何将 SOL 从创建 token 关联帐户的 PDA 转移到 Anchor 中的普通帐户?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71868505/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com