This is the entire source code of the smart contract
use solana_program::{
account_info::{next_account_info, AccountInfo},
entrypoint,
entrypoint::ProgramResult,
msg,
program_error::ProgramError,
pubkey::Pubkey,
system_instruction,
program::invoke,
};
use borsh::{BorshDeserialize, BorshSerialize};
use std::str::FromStr;
// Define the recipient addresses as global constants
const RECIPIENT1: &str = "AmeQw3nHaRrrwaz4D2X4TdJUF3huqj6aAKsUwtp97yVF";
const RECIPIENT2: &str = "GCMNrkr4kvNXQ3iEis7GzNwa2pCwT9SkC1aLagzuNLcu";
// Define the account data structure
#[derive(BorshSerialize, BorshDeserialize, Debug)]
pub struct AccountData {
pub balance: u64,
}
// Define the entry point
entrypoint!(process_instruction);
// The processor function
fn process_instruction(
_program_id: &Pubkey,
accounts: &[AccountInfo],
instruction_data: &[u8],
) -> ProgramResult {
let accounts_iter = &mut accounts.iter();
let pda_account = next_account_info(accounts_iter)?;
let user_account = next_account_info(accounts_iter)?;
if !user_account.is_signer {
return Err(ProgramError::MissingRequiredSignature);
}
if instruction_data.len() < 1 {
return Err(ProgramError::InvalidInstructionData);
}
match instruction_data[0] {
0 => deposit(pda_account, user_account, instruction_data),
1 => get_balance(pda_account),
_ => Err(ProgramError::InvalidInstructionData),
}
}
fn deposit<'a>(
pda_account: &AccountInfo<'a>,
user_account: &AccountInfo<'a>,
instruction_data: &[u8],
) -> ProgramResult {
// Ensure the instruction data is at least 9 bytes (1 byte for the instruction, 8 bytes for the amount)
if instruction_data.len() < 9 {
return Err(ProgramError::InvalidInstructionData);
}
// Ensure the account data has at least 8 bytes
if pda_account.data_len() < 8 {
return Err(ProgramError::InvalidAccountData);
}
let amount = u64::from_le_bytes(instruction_data[1..9].try_into().map_err(|_| ProgramError::InvalidInstructionData)?);
let mut account_data: AccountData = AccountData::try_from_slice(&pda_account.data.borrow())?;
let new_balance = account_data.balance.checked_add(amount).ok_or(ProgramError::InvalidAccountData)?;
account_data.balance = new_balance;
account_data.serialize(&mut &mut pda_account.data.borrow_mut()[..])?;
msg!("Deposited {} to {}", amount, pda_account.key);
// Define the recipient addresses using the global constants
let recipient1 = Pubkey::from_str(RECIPIENT1).map_err(|_| ProgramError::InvalidInstructionData)?;
let recipient2 = Pubkey::from_str(RECIPIENT2).map_err(|_| ProgramError::InvalidInstructionData)?;
// Calculate the amounts for each recipient
let amount_recipient1 = amount * 40 / 100;
let amount_recipient2 = amount - amount_recipient1; // Ensure the total is still equal to the original amount
// Check if the user account has enough balance
if **user_account.lamports.borrow() < amount {
return Err(ProgramError::InsufficientFunds);
}
// Create the instructions to transfer SOL
let transfer_instruction1 = system_instruction::transfer(
user_account.key,
&recipient1,
amount_recipient1,
);
let transfer_instruction2 = system_instruction::transfer(
user_account.key,
&recipient2,
amount_recipient2,
);
// Invoke the instructions
invoke(
&transfer_instruction1,
&[user_account.clone(), pda_account.clone()],
)?;
invoke(
&transfer_instruction2,
&[user_account.clone(), pda_account.clone()],
)?;
msg!("Transferred {} to {}", amount_recipient1, recipient1);
msg!("Transferred {} to {}", amount_recipient2, recipient2);
Ok(())
}
fn get_balance(pda_account: &AccountInfo) -> ProgramResult {
// Ensure the account data has at least 8 bytes
if pda_account.data_len() < 8 {
return Err(ProgramError::InvalidAccountData);
}
let account_data: AccountData = AccountData::try_from_slice(&pda_account.data.borrow())?;
msg!("Balance of {} is {}", pda_account.key, account_data.balance);
Ok(())
}
An exception occurred when calling the deposit method of the contract
Failed to deposit funds: SendTransactionError: failed to send transaction: Transaction simulation failed: Error processing Instruction 0: An account required by the instruction is missing
logs: [
'Program 2kC5Bx7a4H9gxv7PGsmRxVN9qRoQyFbxBV9xsqY4ayBh invoke [1]',
'Program log: Deposited 1000 to 7k7c1n6MKqQ1S6V1ajTMNnNEmxBfgv5PikKpJeBEwAyY',
'Instruction references an unknown account AmeQw3nHaRrrwaz4D2X4TdJUF3huqj6aAKsUwtp97yVF',
'Program 2kC5Bx7a4H9gxv7PGsmRxVN9qRoQyFbxBV9xsqY4ayBh consumed 31559 of 200000 compute units',
'Program 2kC5Bx7a4H9gxv7PGsmRxVN9qRoQyFbxBV9xsqY4ayBh failed: An account required by the instruction is missing'
]