Build on Solana
Review III - Implementing Add_Review
In this lesson, we are going to see how we can create a review and store it.
Here is the changes we have made to lib.rs in this video:
pub mod instruction; pub mod state; use borsh::BorshSerialize; use crate::instruction::ReviewInstruction; use crate::state::AccountState; use crate::state::ReviewError; use solana_program::{ account_info::{next_account_info, AccountInfo}, borsh0_10::try_from_slice_unchecked, entrypoint, entrypoint::ProgramResult, msg, program::invoke_signed, program_error::ProgramError, program_pack::IsInitialized, pubkey::Pubkey, system_instruction, sysvar::{rent::Rent, Sysvar}, }; use std::convert::TryInto; entrypoint!(process_instruction); pub fn process_instruction( program_id: &Pubkey, accounts: &[AccountInfo], instruction_data: &[u8], ) -> ProgramResult { let instruction = ReviewInstruction::unpack(instruction_data)?; match instruction { ReviewInstruction::AddReview { title, rating, description, } => add_review(program_id, accounts, title, rating, description), ReviewInstruction::UpdateReview { title, rating, description, } => update_review(program_id, accounts, title, rating, description), } } pub fn add_review( program_id: &Pubkey, accounts: &[AccountInfo], title: String, rating: u8, description: String, ) -> ProgramResult { msg!("Adding review..."); msg!("Title: {}", title); msg!("Rating: {}", rating); msg!("Description: {}", description); let account_info_iter = &mut accounts.iter(); let initializer = next_account_info(account_info_iter)?; let pda_account = next_account_info(account_info_iter)?; let system_program = next_account_info(account_info_iter)?; if !initializer.is_signer { msg!("Missing required signature"); return Err(ProgramError::MissingRequiredSignature); } let (pda, bump_seed) = Pubkey::find_program_address( &[initializer.key.as_ref(), title.as_bytes().as_ref()], program_id, ); if pda != *pda_account.key { msg!("Invalid seeds for PDA"); return Err(ProgramError::InvalidArgument); } if rating > 10 || rating < 1 { return Err(ReviewError::InvalidRating.into()); } let account_len: usize = 1000; let rent = Rent::get()?; let rent_lamports = rent.minimum_balance(account_len); invoke_signed( &system_instruction::create_account( initializer.key, pda_account.key, rent_lamports, account_len.try_into().unwrap(), program_id, ), &[ initializer.clone(), pda_account.clone(), system_program.clone(), ], &[&[ initializer.key.as_ref(), title.as_bytes().as_ref(), &[bump_seed], ]], )?; msg!("PDA created: {}", pda); msg!("unpacking state account"); let mut account_data = try_from_slice_unchecked::<AccountState>(&pda_account.data.borrow()).unwrap(); msg!("borrowed account data"); msg!("checking if account is already initialized"); if account_data.is_initialized() { msg!("Account already initialized"); return Err(ProgramError::AccountAlreadyInitialized); } account_data.title = title; account_data.rating = rating; account_data.description = description; account_data.is_initialized = true; msg!("serializing account"); account_data.serialize(&mut &mut pda_account.data.borrow_mut()[..])?; msg!("state account serialized"); Ok(()) }
Comments
Anonymous
You need to enroll in the course to be able to comment!