Solana Anchor 传递非自有账户信息以转移 SOL
Solana Anchor passing Non Owned Account Info to Transfer SOL
我需要一个程序来将 PDA
拥有的 SOL 分发到另一个帐户。
如下定义 distribute
指令的上下文。
#[derive(Accounts)]
pub struct Pool<'info> {
#[account(
mut,
seeds = [
b"pool_account".as_ref()],
bump = pool_account.pool_account_bump
)
]
pool_account: Account<'info, PoolState>,
#[account()]
soho_account: Account<'info, PoolState>
}
distribute
指令是
pub fn distribute(ctx: Context<Pool>) -> ProgramResult {
let pool_account = &ctx.accounts.pool_account;
let pool_account_balance = pool_account.to_account_info().lamports();
let soho_account = &ctx.accounts.soho_account;
println!("Distributing {:?} lamports ", pool_account_balance,);
let from_pub_key = pool_account.to_account_info().key;
let to_pub_key = soho_account.to_account_info().key;
let ix = system_instruction::transfer(from_pub_key, to_pub_key, pool_account_balance);
anchor_lang::solana_program::program::invoke(
&ix,
&[
ctx.accounts.pool_account.to_account_info(),
soho_account.to_account_info()
],
)?;
Ok(())
}
测试
it(`Distrubutes funds to shareholders`, async () => {
let [poolAccount, poolAccountBump] = await web3.PublicKey.findProgramAddress(
[Buffer.from("pool_account")],
program.programId
)
// Airdrop SOL to pool account PDA
const connection = await anchor.getProvider().connection;
let signature = await connection.requestAirdrop(poolAccount, LAMPORTS_PER_SOL)
await connection.confirmTransaction(signature);
balance = await connection.getBalance(poolAccount);
console.log(`Pool Account: ${poolAccount} balance: ${balance}`)
assert.ok(balance == 1000953520, `Program account has ${balance}`)
const sohoAccount = anchor.web3.Keypair.generate();
signature = await connection.requestAirdrop(sohoAccount.publicKey, LAMPORTS_PER_SOL)
await connection.confirmTransaction(signature);
await program.rpc.distribute({
accounts: {
poolAccount: poolAccount,
sohoAccount: sohoAccount.publicKey,
// soho2: soho2.publicKey,
}
})
})
当我 运行 测试 distribute
指令时,测试失败 w/
Error: 3007: The given account is owned by a different program than expected
留言。
基本上,它希望 soho_account
归程序所有。但是它应该是一个外部帐户。
system
转移要求 from
帐户至少是系统拥有的帐户。不是 PDA,也不是程序拥有的帐户。
如果您的程序 owned
PDA,那么您的程序可以从它转移到任何帐户,而无需调用系统转移。
参见食谱:https://solanacookbook.com/references/programs.html#transferring-lamports
我需要一个程序来将 PDA
拥有的 SOL 分发到另一个帐户。
如下定义 distribute
指令的上下文。
#[derive(Accounts)]
pub struct Pool<'info> {
#[account(
mut,
seeds = [
b"pool_account".as_ref()],
bump = pool_account.pool_account_bump
)
]
pool_account: Account<'info, PoolState>,
#[account()]
soho_account: Account<'info, PoolState>
}
distribute
指令是
pub fn distribute(ctx: Context<Pool>) -> ProgramResult {
let pool_account = &ctx.accounts.pool_account;
let pool_account_balance = pool_account.to_account_info().lamports();
let soho_account = &ctx.accounts.soho_account;
println!("Distributing {:?} lamports ", pool_account_balance,);
let from_pub_key = pool_account.to_account_info().key;
let to_pub_key = soho_account.to_account_info().key;
let ix = system_instruction::transfer(from_pub_key, to_pub_key, pool_account_balance);
anchor_lang::solana_program::program::invoke(
&ix,
&[
ctx.accounts.pool_account.to_account_info(),
soho_account.to_account_info()
],
)?;
Ok(())
}
测试
it(`Distrubutes funds to shareholders`, async () => {
let [poolAccount, poolAccountBump] = await web3.PublicKey.findProgramAddress(
[Buffer.from("pool_account")],
program.programId
)
// Airdrop SOL to pool account PDA
const connection = await anchor.getProvider().connection;
let signature = await connection.requestAirdrop(poolAccount, LAMPORTS_PER_SOL)
await connection.confirmTransaction(signature);
balance = await connection.getBalance(poolAccount);
console.log(`Pool Account: ${poolAccount} balance: ${balance}`)
assert.ok(balance == 1000953520, `Program account has ${balance}`)
const sohoAccount = anchor.web3.Keypair.generate();
signature = await connection.requestAirdrop(sohoAccount.publicKey, LAMPORTS_PER_SOL)
await connection.confirmTransaction(signature);
await program.rpc.distribute({
accounts: {
poolAccount: poolAccount,
sohoAccount: sohoAccount.publicKey,
// soho2: soho2.publicKey,
}
})
})
当我 运行 测试 distribute
指令时,测试失败 w/
Error: 3007: The given account is owned by a different program than expected
留言。
基本上,它希望 soho_account
归程序所有。但是它应该是一个外部帐户。
system
转移要求 from
帐户至少是系统拥有的帐户。不是 PDA,也不是程序拥有的帐户。
如果您的程序 owned
PDA,那么您的程序可以从它转移到任何帐户,而无需调用系统转移。
参见食谱:https://solanacookbook.com/references/programs.html#transferring-lamports