Ken*_*Heo 5 rust solana anchor-solana
如果一旦将 PDA 创建为关联代币地址,就无法将 SOL 从 PDA 转移到另一个帐户?
我想使用单个 PDA 帐户转移 SOL 和 SPL 令牌。
我尝试了solana_program::program::invoke_signed和system_instruction::transfer。try_borrow_mut_lamports()但是,它不起作用。
每当使用 system_program 进行传输时,我都是Transfer: 从 must not carry data,另一种方式是instruction spent from the balance of an account it does not own。
我缺少什么?
我可以得到一些建议吗?
谢谢。
Struct 中的关联令牌帐户
#[account(init,
seeds = [authority.to_account_info().key.as_ref()],
bump,
payer = authority,
token::mint = mint,
token::authority = authority)
]
pub vault: Account<'info, TokenAccount>,
Run Code Online (Sandbox Code Playgroud)
创建另一个 PDA,用于从保管库帐户转移 spl 令牌时的权限
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))?;
Run Code Online (Sandbox Code Playgroud)
失败案例 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)?;
Run Code Online (Sandbox Code Playgroud)
失败案例 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;
Run Code Online (Sandbox Code Playgroud)
无法从同一账户同时转移 SOL 和 SPL 代币。SPL 代币账户(关联或未关联)归 SPL 代币程序所有,这意味着只有 SPL 代币程序才能更改其数据并扣除其 lamport。否则,任何人都有可能将代币账户置于租金豁免之下并破坏代币计划的保证。
让我们回顾一下您的案例并解释为什么它们不起作用:
system_program触发将 SOL 从保管库转移给所有者:Transfer: from must not carry data这里实际上有两个错误,但只报告了第一个。当您尝试从保管库中进行操作时system_instruction::transfer,主要会失败,因为保管库不属于系统程序。它由令牌程序拥有,因此只有令牌程序可以移动其灯,而系统程序则不能。报告的失败表明该帐户还有数据,即代币数据(所有者、金额、委托人等)。
这个非常相似——不是系统程序试图从令牌帐户中扣除 lamport,而是你的程序试图这样做,所以运行时会再次说“这是不允许的”。
| 归档时间: |
|
| 查看次数: |
2208 次 |
| 最近记录: |