0

use borsh::{BorshDeserialize, BorshSerialize}; use solana_program::{ account_info::{next_account_info, AccountInfo}, entrypoint, entrypoint::ProgramResult, msg, pubkey::Pubkey, program_error::ProgramError, };

#[derive(BorshSerialize, BorshDeserialize, Debug)] pub struct LinkRecord { pub payer_address: Pubkey, pub link: String, }

#[derive(BorshSerialize, BorshDeserialize, Debug, Default)] pub struct LinkRecords { pub records: Vec, }

entrypoint!(process_instruction);

fn process_instruction( program_id: &Pubkey, accounts: &[AccountInfo], instruction_data: &[u8], ) -> ProgramResult { msg!("Instruction: Save Link and Payer Address");

let accounts_iter = &mut accounts.iter();

let storage_account = next_account_info(accounts_iter)?;

let payer_account = next_account_info(accounts_iter)?;

if !storage_account.is_writable {
    return Err(ProgramError::InvalidAccountData);
}

let link = String::from_utf8(instruction_data.to_vec()).map_err(|_| ProgramError::InvalidInstructionData)?;

let mut records: LinkRecords = match LinkRecords::try_from_slice(&storage_account.data.borrow()) {
    Ok(data) => data,
    Err(_) => LinkRecords::default(),
};

let new_record = LinkRecord {
    payer_address: *payer_account.key,
    link,
};
records.records.push(new_record);
let serialized_data = records.try_to_vec().map_err(|_| ProgramError::InvalidAccountData)?;
if serialized_data.len() > storage_account.data.borrow_mut().len() {
    return Err(ProgramError::AccountDataTooSmall);
}
storage_account.data.borrow_mut()[..serialized_data.len()].copy_from_slice(&serialized_data);
Ok(())

}

This is a sample contract to store address and a link I have created, but after every transaction, the data stored in the state_account is overwritten, I am unable to understand why it happens, Can somebody guide me pls?

1 Answer 1

1

The last line of the program writes bytes to the account:

storage_account.data.borrow_mut()[..serialized_data.len()].copy_from_slice(&serialized_data);

Every single time you call this instruction, serialized_data is written into the account, which is why it's updated every time.

2
  • How can I correct it, so the data is not overwritten? Mar 19 at 7:25
  • You can add a check to see if that account has any data. A typical convention is to write an "account discriminator", between 1 and 8 bytes that uniquely identify the account type. In your case, you can write the byte 1 as the first byte in the account. Then during your program, if the first byte in storage_account is 1, you program can return an error. This way an account cannot be overwritten
    – Jon C
    Mar 19 at 23:47

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.