3

I am new to solana. How can I verify if a PDA exists inside a solana Rust program. I checked online docs and google for blogs. I did not find the answer.

So what I am trying to is a user call one of my program instruction. I will use this user's public key and the program Id to find a pda. And then check if this pda exists. If it does not, I will create a PDA for this user as the user profile. So how can I check the existence of the PDA?

Thank you!

Thanks for the replying. Let me give more info. First, I am not using Anchor. It is solana plain rust program. And what I want to do is as follows:

pub fn do_something(
program_id: &Pubkey,
accounts: &[AccountInfo],
other: String
) -> ProgramResult {
let account_info_iter = &mut accounts.iter();

let initializer = next_account_info(account_info_iter)?;
let profile_pda_account = next_account_info(account_info_iter)?;

// validation
let (profile_pda, bump_seed) =
    Pubkey::find_program_address(&[initializer.key.as_ref()], program_id);
if profile_pda != *profile_pda_account.key {
    msg!(
        "Invalid seeds for PDA. input={}, calulated={}",
        profile_pda_account.key,
        profile_pda
    );
    return Err(ProgramError::InvalidArgument);
}

// check existense
if //profile_pda_account not exist {
    //create the pda
}
// do something
//...
}
3
  • Is this in Anchor or plain Solana? Also do you have to check? Do you have something against trying to create the PDA anyways and trusting that it'll fail if it already exists?
    – Ademola
    Commented Aug 30, 2022 at 13:23
  • Thanks @Ademola. It is plain Solana. Please see my above code. I do not just want to error our if it exist. I need to do something else based on the content of this pda if it exists Commented Aug 30, 2022 at 17:07
  • Got it. I'm adding an answer now
    – Ademola
    Commented Aug 30, 2022 at 20:24

2 Answers 2

3

check inside program

Add #[account(init_if_needed)] constraint to your account (in Anchor) this will initialize the PDA only if it's not already initialized.

check off-chain

First, you need to get the PDA address, you'll have to use something like PublicKey.findProgramAddress source. then get the account info of the PDA which will return - if the requested account doesn't exist.

Keep in mind that all accounts in Solana are System Accounts by default. Even if it's never been initialized. So unless you are working with token accounts or data accounts. You don't have to check.

4
  • Thanks for the comment. I am not using Anchor. I updated my question, adding more info. Could you please take another look? Thank you! Commented Aug 30, 2022 at 17:05
  • it follows the same off-chain check principle but it's easier since you have access to account info of any account that is passed to your program implicitly. You can check if the data exists if so it's initialized.
    – vicyyn
    Commented Aug 30, 2022 at 17:39
  • Hi @vicyyn, how to check if the data exists in rust? I am also not very familiar with rust. LOL Commented Aug 31, 2022 at 3:02
  • in your accounts, your accounts Infos have values like rent epoch and data docs.rs/solana-program/1.5.0/solana_program/account_info/… You can simply view if there's data allocated, also you can check if the rent epoch is a valid number, it should be something like 0 or a weird number~ if it's not rent exempt.
    – vicyyn
    Commented Aug 31, 2022 at 8:46
1

The code in our instruction that checks if an account is already initialized is something like:

if **profile_pda_account.try_borrow_lamports()? > 0 {
       msg!("This account has been initialized");
       initialized = true;
} else {
       msg!("Account is not initialized");
       initialized = false;
}

Uninitialized accounts have 0 lamports.

8
  • Do you mean if the pda exists, then the lamports must > 0? Is it possible that the lamports were consumed to 0 by this pda, or it guarantees the pda's lamports cannot be used except it is deleted? Commented Aug 31, 2022 at 3:05
  • An account can have >0 lamports and still be non initialized, any System Account can receive sol.
    – vicyyn
    Commented Aug 31, 2022 at 8:43
  • 1
    @ZhihengXie Yes. An account is closed as soon as its balance runs down to 0 lamports(validators delete it to save disk space as it's not paid for anymore).
    – Ademola
    Commented Aug 31, 2022 at 10:50
  • @vicyyn Sending sol to a non-initialized account is how it is initialized.
    – Ademola
    Commented Aug 31, 2022 at 10:55
  • Is it possible to initialize an account that has sol? e.g. System Account
    – vicyyn
    Commented Aug 31, 2022 at 11:00

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.