2

I have a simple program:


#[program]
pub mod my_cool_project {
    use super::*;

    pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
        let counter = &mut ctx.accounts.counter;
        counter.count = 0;
        Ok(())
    }

}

#[derive(Accounts)]
pub struct Initialize<'info> {
    #[account(init, payer = user, space = 8 + 8)]
    pub counter: Account<'info, Counter>,
    #[account(mut)]
    pub user: Signer<'info>,
    pub system_program: Program<'info, System>,
}

#[account]
pub struct Counter {
    pub count: u64,
}

When I try to test the initialize instruction:

import * as anchor from "@project-serum/anchor";
import { Program } from "@project-serum/anchor";
import { MyCoolProject } from "../target/types/my_cool_project";

describe("my-cool-project", () => {
  // Configure the client to use the local cluster.
  anchor.setProvider(anchor.AnchorProvider.env());

  const program = anchor.workspace.MyCoolProject as Program<MyCoolProject>;

  it("Is initialized!", async () => {
    // Add your test here.
    const tx = await program.methods.initialize().rpc();
    console.log("Your transaction signature", tx);
  });
});

I get this error:

  1) my-cool-project
       Is initialized!:
     Error: AnchorError thrown in programs/my-cool-project/src/lib.rs:28. Error Code: TryingToInitPayerAsProgramAccount. Error Number: 4101. Error Message: You cannot/should not initialize the payer account as a program account.

What am I doing wrong?

2 Answers 2

3

The different accounts defined in the Initialize<'info> struct of your Rust code are expected to be passed in by the client. Your on-chain code expects three accounts: the counter, the user, and the system program.

Your code should look like this:

// First generate the account to initialize as your counter state
let counter = anchor.web3.Keypair.generate();

// Next you get your provider
const provider = anchor.AnchorProvider.env();

await program.methods
  .initialize()
  .accounts({
    counter: counter.publicKey,
    user: provider.publicKey,
    systemProgram: anchor.web3.SystemProgram.programId,
  })
  .signers([counter])
  .rpc();

Your provider is the wallet you initialized during your Solana installation. Here we define it as the user to pay for creation of the counter. Make sure there's enough sol in it using solana balance | solana airdrop 1 in your cli.

In the signers array we add the counter because every account needs to sign its own creation. The account we specify as the user also needs to sign the transaction to approve the cost of payer = user; Howeever, here we don't specify provider as a signer because as your default solana-cli wallet, it signs every transaction automatically.

1

Your program expects a counter account as parameter. Change your test to this and it will work:

  const counter = anchor.web3.Keypair.generate()

  it("Is initialized!", async () => {
    const tx = await program.methods
      .initialize()
      .accounts({ counter: counter.publicKey })
      .signers([counter])
      .rpc()

    const account = await program.account["counter"].fetch(counter.publicKey)
    expect(account.count.toNumber() === 0)
  })

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.