I am working on a simple project, where a wallet account is created, credited some SOL, then assigned a program contract as its owner (via assign
instruction). In the use case, the program should control the wallet's account funds.
The program code updates the balance of the owned account.
However, it is failing with a "instruction changed the balance of a read-only account" (which intrigues me, considering Solana Docs - https://docs.solana.com/developing/programming-model/accounts#:~:text=The%20security%20model%20enforces%20that,them%20via%20accounts%20they%20own.)
Transaction Instruction keys hold references to both accounts as 'isWritable: true', and transaction is signed with the program's key.
Any guidance is much appreciated.
The code is as follows:
pub fn process_instruction(
program_id: &Pubkey,
accounts: &[AccountInfo],
instruction_data: &[u8],
) -> ProgramResult {
let accounts_iter = &mut accounts.iter();
let owned_account = next_account_info(accounts_iter)?;
let owner = next_account_info(accounts_iter)?;
msg!("Owned Account: {:?}", owned_account);
msg!("Owner: {:?}", owner);
if owned_account.owner != program_id {
msg!("This account is not owned by the program");
return Err(ProgramError::IncorrectProgramId);
}
if owned_account.lamports() < 111111111 {
msg!("Insufficient funds in the owned account");
return Err(ProgramError::InsufficientFunds);
}
**owned_account.lamports.borrow_mut() -= 111111111;
**owner.lamports.borrow_mut() += 111111111;
msg!("Transferred 111111111 lamports from the owned account to the owner");
// gracefully exit the program
Ok(())
}