0

currently I have the following in a program:

**main_data_account.try_borrow_mut_lamports()? -= final_transfer; **player_account_info.try_borrow_mut_lamports()? += final_transfer;

where player_account_info is the SOL account of the signer interacting with the program, and main_data_account is the PDA owned by the program. You can see the account here: https://explorer.solana.com/address/CkX5cVqHxiPo3D3S5KRFvFY84vDjx4kCHn4YKYSMcBpi?cluster=devnet

However, this confuses users, because it doesn't show up as a transfer instruction.. so i wanted to try and do:

invoke_signed(
    &system_instruction::transfer( main_data_account.key, player_account_info.key, final_transfer),
    &[main_data_account.clone(), player_account_info.clone()],
    &[&[state::MAIN_ACCOUNT_SEED, &[main_bump_seed]]]
)?;

However this yields the following error:

Instruction spent from the balance of an account it does not own

I'm afraid I don't really understand the problem.. does transfer only work if the system program is the owner of the account? The program was set as the owner in the create_account instruction that made the PDA.

Thanks

1 Answer 1

2

does transfer only work if the system program is the owner of the account?

Yes. Only the program that owns an account is allowed to change its state. Here since it's a PDA, the system program can no longer change its balance; only your program can.

1
  • I would clarify that it's not because it's a PDA that the system program can no longer change its balance, but because the account is owned by the program. A PDA that is not owned by the program must use system_program::transfer
    – Jon C
    Apr 6, 2023 at 11:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.