1

I'm facing an issue in my instruction trying to generate a PDA from a string and user.key(), just like in the PDA Anchor tutorial. I tried it in various ways and still, I get the same error: Error: failed to send transaction: Transaction simulation failed: Error processing Instruction 0: custom program error: 0x0

This is my instruction:

#[derive(Accounts)]

pub struct CreateCollection<'info> {
    #[account(
        init, 
        payer=user, 
        space = 8 + 32 + 1,
        seeds = [b"user-collection", user.key().as_ref()],
        bump
    )]
    pub collection: Account<'info, Collection>,
    #[account(mut)]
    pub user: Signer<'info>,
    pub system_program: Program<'info, System>,
}

pub fn handler(
    ctx: Context<CreateCollection>, 
) -> Result<()> {

    let collection = &mut ctx.accounts.collection;
    let user = &ctx.accounts.user;
    
    collection.user = *user.key;
    collection.bump = *ctx.bumps.get("collection").unwrap();

    Ok(())

}

#[account]
pub struct Collection {
    pub user: Pubkey, 
    pub bump: u8,  
}

And this is my test:

it("Can create a Collection", async () => {
    
    const [collectionPublicKey, _] = web3.PublicKey.findProgramAddressSync(
      [Buffer.from("user-collection"), anchorProvider.wallet.publicKey.toBuffer()],
      program.programId,
    )

    
    await program.methods
    .createCollection()
    .accounts({
        collection: collectionPublicKey,
        user: anchorProvider.wallet.publicKey,
        systemProgram: web3.SystemProgram.programId,
    })
    .rpc()

    let account = await program.account.collection.fetch(collectionPublicKey)
    console.log(JSON.stringify(account, null, 2))
    console.log(collectionPublicKey)
  });

1 Answer 1

2

Are you running the test on devnet? If so, the error you're encountering could be due to the account having been initialized previously. Since you're using the wallet pubkey as one of the seeds, it means each wallet can only create one Collection account from your program. If the same wallet invokes the instruction again, then the transaction will fail because the account already exists.

You can try updating Anchor.toml and then run anchor test on localnet:

[programs.localnet]
...

[provider]
cluster = "localnet"
2
  • Yep. That was my mistake. Thanks for the clarification. The account was already initialized. But also i had to change b"user-collection", to b"collection".as_ref(), without the underscore. BTW. What happen if i want the user can create multiple collections? Should i need to add a counter as a seed too?
    – 0xNicko
    Commented Apr 28, 2023 at 0:37
  • yea that should work, you may need create another account to store the count
    – john
    Commented Apr 28, 2023 at 2:41

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.