---
title: Build Your First Program
description:
  Create a local Anchor program, build and test it, and walk through every file
  in the default counter program.
h1: Build Your First Solana Program
---

This quickstart uses the [Anchor framework](https://www.anchor-lang.com/docs)
starter project generated by `anchor init`. You will create the project locally,
run its tests, build the program, and walk through the program code that Anchor
generates.

## Prerequisites

Before you start,
[install the Solana development tools](/docs/intro/installation). The
installation includes Rust, the Solana CLI, and the Anchor CLI.

Use Anchor CLI version 1.1.2 or higher for this template. Check your installed
version:

```terminal
$ anchor --version
```

<Steps>

<Step>

### Create the project

Run the following commands in your terminal:

```terminal
$ anchor init my-program
$ cd my-program
```

The starter project includes one Solana program under `programs/my-program`. The
program includes two instructions: one to initialize a counter account and one
to increment the counter.

Some parts of the template demonstrate common Solana program patterns: deriving
[PDA](/docs/core/pda) account addresses, making a Cross Program Invocation
([CPI](/docs/core/cpi)) to transfer SOL, and using custom error checks to stop
an instruction when a condition fails.

<Files>
  <Folder name="my-program" defaultOpen>
    <File name="Anchor.toml" />
    <File name="Cargo.toml" />
    <Folder name="programs" defaultOpen>
      <Folder name="my-program" defaultOpen>
        <File name="Cargo.toml" />
        <Folder name="src" defaultOpen>
          <File name="lib.rs" />
          <File name="constants.rs" />
          <File name="error.rs" />
          <File name="instructions.rs" />
          <Folder name="instructions" defaultOpen>
            <File name="initialize.rs" />
            <File name="increment.rs" />
          </Folder>
          <File name="state.rs" />
        </Folder>
        <Folder name="tests" defaultOpen>
          <File name="test_initialize.rs" />
        </Folder>
      </Folder>
    </Folder>
  </Folder>
</Files>

</Step>

<Step>

### Build Program

Run `anchor build` to compile the starter program:

```terminal
$ anchor build
```

The compiled program is written to `target/deploy/my_program.so`. When the
program is deployed, the contents of this `.so` file are stored in an account
onchain.

</Step>

<Step>

### Run Test

Run the default test:

```terminal
$ anchor test
```

This template's `Anchor.toml` uses the Rust test command:

```toml title="Anchor.toml"
skip_local_validator = true

[scripts]
test = "cargo test"
```

The test loads the compiled program into [LiteSVM](https://www.litesvm.com/),
creates a payer, sends the _rs`initialize`_ and _rs`increment`_ instructions,
then checks the counter account state.

Running `anchor test` also compiles the program, so you do not need to run
`anchor build` first when testing locally.

</Step>

<Step>

### Deploy Program

Local tests are the fastest feedback loop. When you are ready to deploy to a
network, for example devnet, build first, then deploy to a cluster.

Deploying a Solana program requires SOL because the program is stored in an
account, and the account must pay for the space it uses. On devnet, request free
devnet SOL from the [Solana Faucet](https://faucet.solana.com/) or with the
Solana CLI:

```terminal
$ solana airdrop 2 --url devnet
```

```terminal
$ anchor build
$ anchor deploy --provider.cluster devnet
```

</Step>

</Steps>

## Source files

The `src` directory contains the Solana program. Anchor's
[Program Structure](https://www.anchor-lang.com/docs/basics/program-structure)
docs explain the core macros used here, including _rs`declare_id!`_,
_rs`#[program]`_, _rs`#[derive(Accounts)]`_, and _rs`#[account]`_. This section
walks through the template files.

### lib.rs

`lib.rs` is the program entrypoint. It connects the source files, defines the
program address, and defines the program instructions that users can call.

<WithNotes>

```rust title="programs/my-program/src/lib.rs" -w
// !tooltip[/pub mod constants/] constantsMod
pub mod constants;
// !tooltip[/pub mod error/] errorMod
pub mod error;
// !tooltip[/pub mod instructions/] instructionsMod
pub mod instructions;
// !tooltip[/pub mod state/] stateMod
pub mod state;

// !tooltip[/anchor_lang::prelude/] prelude
use anchor_lang::prelude::*;

pub use constants::*;
pub use instructions::*;
pub use state::*;

// !tooltip[/declare_id!/] declareId
declare_id!("82sFkffP9wxwpyfZyeaKHH2chQoJPUGsJZSPi9mrUuXd");

// !tooltip[/#\[program\]/] programMacro
#[program]
pub mod my_program {
    use super::*;

    // !tooltip[/pub fn initialize/] publicInstructions
    pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
        // !tooltip[/handle_initialize/] handlers
        crate::instructions::initialize::handle_initialize(ctx)
    }

    // !tooltip[/pub fn increment/] publicInstructions
    pub fn increment(ctx: Context<Increment>) -> Result<()> {
        // !tooltip[/handle_increment/] handlers
        crate::instructions::increment::handle_increment(ctx)
    }
}
```

### !constantsMod

_rs`pub mod constants`_ makes `constants.rs` part of the program crate. This is
where the template keeps shared program values such as the PDA seed, transfer
amount, and maximum counter value.

### !errorMod

_rs`pub mod error`_ makes `error.rs` part of the program crate. This file
defines the custom errors that the program can return when an instruction is
invalid.

### !instructionsMod

_rs`pub mod instructions`_ makes `instructions.rs` part of the program crate.
That file works like an index for the instruction-specific files in
`src/instructions/`.

### !stateMod

_rs`pub mod state`_ makes `state.rs` part of the program crate. This file
defines the data layout for accounts owned by this program, including the
_rs`Counter`_ account.

### !prelude

_rs`anchor_lang::prelude::*`_ imports the Anchor types and macros used to define
a Solana program, including _rs`Context`_, _rs`Result`_, _rs`Pubkey`_,
_rs`Account`_, _rs`Signer`_, and Anchor account attributes.

### !reexports

The _rs`pub use`_ lines make public items from the child modules available from
the crate root. That keeps the instruction entrypoints short, such as
_rs`Context<Initialize>`_ instead of a longer module path.

### !declareId

_rs`declare_id!`_ defines the program's address. It should match the address in
`Anchor.toml`, the deployed program account, and any users or tests that call
the program.

### !programMacro

_rs`#[program]`_ tells Anchor to generate the Solana program entrypoint and
instruction dispatch code. Public functions in this module become the
instructions that users can call.

### !publicInstructions

_rs`initialize`_ and _rs`increment`_ are the two instruction names users can
call. Each receives a _rs`Context<T>`_. The type inside _rs`Context`_ defines
the accounts required by that instruction, and Anchor validates those accounts
before the instruction runs.

### !handlers

The handler function contains the logic for the instruction.

</WithNotes>

<SideBySide>

### !left

```toml title="Anchor.toml" -w
[programs.localnet]
# !mark
my_program = "82sFkffP9wxwpyfZyeaKHH2chQoJPUGsJZSPi9mrUuXd"
```

### !right

```rust title="lib.rs" -w
// !mark
declare_id!("82sFkffP9wxwpyfZyeaKHH2chQoJPUGsJZSPi9mrUuXd");
```

</SideBySide>

The same program address appears in configuration and code. `Anchor.toml` tells
Anchor which address to deploy or call for a cluster. _rs`declare_id!`_ defines
the program address in the program for security checks.

### constants.rs

`constants.rs` keeps shared values in one place. In this template,
_rs`COUNTER_SEED`_ derives the counter PDA, _rs`HELLO_WORLD_LAMPORTS`_ is
transferred during initialization, and _rs`MAX_COUNT`_ is checked before
incrementing.

<WithNotes>

```rust title="programs/my-program/src/constants.rs" -w
use anchor_lang::prelude::*;

// !tooltip[/#\[constant\]/] anchorConstant
// !tooltip[/COUNTER_SEED/] counterSeed
#[constant]
pub const COUNTER_SEED: &[u8] = b"counter";

// !tooltip[/HELLO_WORLD_LAMPORTS/] helloLamports
#[constant]
pub const HELLO_WORLD_LAMPORTS: u64 = 1;

// !tooltip[/MAX_COUNT/] maxCount
#[constant]
pub const MAX_COUNT: u64 = 10;
```

### !anchorConstant

_rs`#[constant]`_ tells Anchor to include the value in the program IDL. That
makes important program constants visible to generated clients and tooling.

### !counterSeed

_rs`COUNTER_SEED`_ is the byte string used to derive the counter PDA. The
program and test both use this seed so they agree on the account address without
storing a separate keypair. This template uses one fixed seed, so the program
has one counter address. Real programs often include a user's address or another
identifier in the seeds to create many related accounts.

### !helloLamports

_rs`HELLO_WORLD_LAMPORTS`_ is the amount of lamports transferred from the payer
to the counter account inside _rs`initialize`_. It is deliberately tiny because
the template is demonstrating a CPI to the System Program.

### !maxCount

_rs`MAX_COUNT`_ is the upper bound checked by _rs`increment`_. Keeping it here
gives the program, tests, and generated IDL one shared name for the rule.

</WithNotes>

<SideBySide>

### !left

```rust title="initialize.rs" -w
#[derive(Accounts)]
pub struct Initialize<'info> {
    // ...
    #[account(
        init,
        payer = payer,
        space = 8 + Counter::INIT_SPACE,
        // !mark
        // !mention counter-seed
        seeds = [COUNTER_SEED],
        bump
    )]
    pub counter: Account<'info, Counter>,
    // ...
}

pub fn handle_initialize(ctx: Context<Initialize>) -> Result<()> {
    // ...

    // !mark
    // !mention hello-world-lamports
    anchor_lang::system_program::transfer(cpi_ctx, HELLO_WORLD_LAMPORTS)?;

    Ok(())
}
```

### !right

`initialize.rs` uses two constants:

- [_rs`COUNTER_SEED`_](mention:counter-seed) derives the counter PDA address.
- [_rs`HELLO_WORLD_LAMPORTS`_](mention:hello-world-lamports) sets the amount
  transferred from the payer to the counter account.

</SideBySide>

<SideBySide>

### !left

```rust title="increment.rs" -w
pub fn handle_increment(ctx: Context<Increment>) -> Result<()> {
    // ...

    require!(
        // !mark
        // !mention max-count
        ctx.accounts.counter.count < MAX_COUNT,
        ErrorCode::CounterOverflow,
    );

    ctx.accounts.counter.count += 1;
    Ok(())
}
```

### !right

`increment.rs` uses [_rs`MAX_COUNT`_](mention:max-count) as the counter's upper
bound. If the current count is already at the maximum, _rs`require!`_ returns
_rs`CounterOverflow`_ and the account data is not changed.

</SideBySide>

### state.rs

`state.rs` defines custom data types for accounts the program creates and owns.
The program defines instructions to create, initialize, and update that data,
but the counter data is not stored inside the program itself. It is stored in a
separate account with its own address.

<WithNotes>

```rust title="programs/my-program/src/state.rs" -w
use anchor_lang::prelude::*;

// !tooltip[/#\[account\]/] accountMacro
#[account]
// !tooltip[/InitSpace/] initSpace
#[derive(InitSpace)]
pub struct Counter {
    // !tooltip[/count/] count
    pub count: u64,
    // !tooltip[/authority/] authority
    pub authority: Pubkey,
}
```

### !accountMacro

_rs`#[account]`_ tells Anchor this struct is data that can be stored in an
onchain account owned by this program. Anchor uses it to serialize, deserialize,
and validate _rs`Counter`_ accounts.

### !initSpace

_rs`InitSpace`_ lets Anchor calculate _rs`Counter::INIT_SPACE`_, the number of
bytes needed for this struct's fields. The 8-byte Anchor account discriminator
is added separately when the account is created.

### !count

_rs`count`_ is the counter value stored inside the account data.

### !authority

_rs`authority`_ stores the address allowed to increment the counter.
_rs`initialize`_ writes this address, and _rs`increment`_ requires that same
address to sign.

</WithNotes>

<SideBySide>

### !left

```rust title="initialize.rs" -w
#[account(
    init,
    payer = payer,
    // !mark
    // !mention counter-space
    space = 8 + Counter::INIT_SPACE,
    seeds = [COUNTER_SEED],
    bump
)]
pub counter: Account<'info, Counter>,
// ...

pub fn handle_initialize(ctx: Context<Initialize>) -> Result<()> {
    // !mark(1:2)
    // !mention(1:2) initialize-fields
    ctx.accounts.counter.count = 0;
    ctx.accounts.counter.authority = ctx.accounts.payer.key();

    Ok(())
}
```

```rust title="increment.rs" -w
pub fn handle_increment(ctx: Context<Increment>) -> Result<()> {
    // ...

    // !mark
    // !mention increment-count
    ctx.accounts.counter.count += 1;
    Ok(())
}
```

### !right

`state.rs` defines the _rs`Counter`_ account data. The instruction files use
that type when they create and update the account:

- [_rs`Counter::INIT_SPACE`_](mention:counter-space) sizes the account for the
  fields defined in `state.rs`.
- [_rs`count`_ and _rs`authority`_](mention:initialize-fields) are the field
  values written when the account is initialized.
- [_rs`count += 1`_](mention:increment-count) updates the stored counter value
  after validation passes.

</SideBySide>

### error.rs

`error.rs` defines the program's custom errors. In this template, the errors
demonstrate how instruction handlers stop when a caller is not allowed to update
the counter or the counter has already reached _rs`MAX_COUNT`_.

<WithNotes>

```rust title="programs/my-program/src/error.rs" -w
use anchor_lang::prelude::*;

// !tooltip[/#\[error_code\]/] errorCode
#[error_code]
pub enum ErrorCode {
    // !tooltip[/Unauthorized/] unauthorized
    #[msg("Only the counter authority can update this counter")]
    Unauthorized,
    // !tooltip[/CounterOverflow/] counterOverflow
    #[msg("Counter has reached the maximum value")]
    CounterOverflow,
}
```

### !errorCode

_rs`#[error_code]`_ tells Anchor to turn these variants into custom program
errors. Clients and tests can use those errors instead of guessing from raw
error codes.

### !unauthorized

_rs`Unauthorized`_ is returned when the transaction signer is not the authority
stored in the counter account.

### !counterOverflow

_rs`CounterOverflow`_ is returned when incrementing would break the program's
_rs`MAX_COUNT`_ rule.

</WithNotes>

<SideBySide>

### !left

```rust title="increment.rs" -w
pub fn handle_increment(ctx: Context<Increment>) -> Result<()> {
    require_keys_eq!(
        ctx.accounts.counter.authority,
        ctx.accounts.authority.key(),
        // !mark
        // !mention unauthorized-error
        ErrorCode::Unauthorized,
    );
    require!(
        ctx.accounts.counter.count < MAX_COUNT,
        // !mark
        // !mention overflow-error
        ErrorCode::CounterOverflow,
    );

    ctx.accounts.counter.count += 1;
    msg!("Hello, world! Counter is now {}", ctx.accounts.counter.count);
    Ok(())
}
```

### !right

`error.rs` names the errors that the instruction can return:

- [_rs`ErrorCode::Unauthorized`_](mention:unauthorized-error) is returned when
  the signer is not the authority stored in the counter account.
- [_rs`ErrorCode::CounterOverflow`_](mention:overflow-error) is returned when
  the counter has already reached _rs`MAX_COUNT`_.

</SideBySide>

### instructions.rs

`instructions.rs` connects the instruction files to the program crate so
`lib.rs` can access the _rs`initialize`_ and _rs`increment`_ instruction code.
Each instruction file defines the accounts required by that instruction and the
handler logic that runs after Anchor validates those accounts.

<WithNotes>

```rust title="programs/my-program/src/instructions.rs" -w
// !tooltip[/pub mod initialize/] moduleDeclarations
pub mod initialize;
pub mod increment;

// !tooltip[/pub use initialize/] reexports
pub use initialize::*;
pub use increment::*;
```

### !moduleDeclarations

The _rs`pub mod`_ lines make `src/instructions/initialize.rs` and
`src/instructions/increment.rs` part of the program crate.

### !reexports

The _rs`pub use`_ lines re-export public items from those files. That makes the
instruction account structs and handler functions available through the
_rs`instructions`_ module.

</WithNotes>

### initialize.rs

`initialize.rs` defines the accounts required to create the counter account, and
then writes the account's first values. The _rs`#[derive(Accounts)]`_ struct
uses Anchor
[account constraints](https://www.anchor-lang.com/docs/references/account-constraints)
to say which accounts are required and how the new counter account is created.

<WithNotes>

```rust title="programs/my-program/src/instructions/initialize.rs" -w
use anchor_lang::prelude::*;

use crate::{constants::*, state::Counter};

// !tooltip[/derive\(Accounts\)/] accountsStruct
#[derive(Accounts)]
pub struct Initialize<'info> {
    // !tooltip[/#\[account\(mut\)\]/] payerMutable
    #[account(mut)]
    // !tooltip[/Signer<'info>/] payerSigner
    pub payer: Signer<'info>,
    // !tooltip[/#\[account\(/] counterConstraints
    #[account(
        // !tooltip[/init/] initConstraint
        init,
        // !tooltip[/payer = payer/] payerConstraint
        payer = payer,
        // !tooltip[/space = 8 \+ Counter::INIT_SPACE/] space
        space = 8 + Counter::INIT_SPACE,
        // !tooltip[/seeds = \[COUNTER_SEED\]/] seeds
        seeds = [COUNTER_SEED],
        // !tooltip[/bump/] bump
        bump
    )]
    // !tooltip[/Account<'info, Counter>/] counterAccountType
    pub counter: Account<'info, Counter>,
    // !tooltip[/Program<'info, System>/] systemProgram
    pub system_program: Program<'info, System>,
}

// !tooltip[/handle_initialize/] handler
pub fn handle_initialize(ctx: Context<Initialize>) -> Result<()> {
    // !tooltip[/counter.count = 0/] initialCount
    ctx.accounts.counter.count = 0;
    // !tooltip[/counter.authority = ctx.accounts.payer.key\(\)/] initialAuthority
    ctx.accounts.counter.authority = ctx.accounts.payer.key();

    // !tooltip[/system_program::Transfer/] cpiAccounts
    let cpi_accounts = anchor_lang::system_program::Transfer {
        from: ctx.accounts.payer.to_account_info(),
        to: ctx.accounts.counter.to_account_info(),
    };
    // !tooltip[/CpiContext::new/] cpiContext
    let cpi_ctx = CpiContext::new(anchor_lang::system_program::ID, cpi_accounts);
    // !tooltip[/system_program::transfer/] transfer
    anchor_lang::system_program::transfer(cpi_ctx, HELLO_WORLD_LAMPORTS)?;

    // !tooltip[/msg!/] programLog
    msg!("Hello, world! Counter initialized");
    Ok(())
}
```

<ScrollyCoding>

## !!steps Account Context

The _rs`Initialize`_ struct defines the accounts that must be included when a
user calls the _rs`initialize`_ instruction. Anchor checks these accounts before
the handler runs.

<CodePlaceholder title="initialize.rs" />

```rust !! title="initialize.rs"
// !focus(1:2)
#[derive(Accounts)]
pub struct Initialize<'info> {
    #[account(mut)]
    pub payer: Signer<'info>,
    #[account(
        init,
        payer = payer,
        space = 8 + Counter::INIT_SPACE,
        seeds = [COUNTER_SEED],
        bump
    )]
    pub counter: Account<'info, Counter>,
    pub system_program: Program<'info, System>,
}
```

## !!steps Payer Account

The _rs`payer`_ account pays to create the counter account. The
_rs`Signer<'info>`_ type means the payer must sign the transaction, and
_rs`#[account(mut)]`_ means the payer account can be changed because lamports
will be deducted.

<CodePlaceholder title="initialize.rs" />

```rust !! title="initialize.rs"
#[derive(Accounts)]
pub struct Initialize<'info> {
    // !focus(1:2)
    #[account(mut)]
    pub payer: Signer<'info>,
    #[account(
        init,
        payer = payer,
        space = 8 + Counter::INIT_SPACE,
        seeds = [COUNTER_SEED],
        bump
    )]
    pub counter: Account<'info, Counter>,
    pub system_program: Program<'info, System>,
}
```

## !!steps Counter Account

The _rs`counter`_ account stores the _rs`Counter`_ data from `state.rs`.
_rs`init`_ tells Anchor to create this account before the handler runs, and
_rs`payer = payer`_ tells Anchor which account pays for creation.

<CodePlaceholder title="initialize.rs" />

```rust !! title="initialize.rs"
#[derive(Accounts)]
pub struct Initialize<'info> {
    #[account(mut)]
    pub payer: Signer<'info>,
    // !focus(1:8)
    #[account(
        init,
        payer = payer,
        space = 8 + Counter::INIT_SPACE,
        seeds = [COUNTER_SEED],
        bump
    )]
    pub counter: Account<'info, Counter>,
    pub system_program: Program<'info, System>,
}
```

## !!steps Account Size

The _rs`space`_ constraint tells Anchor how much account data to allocate.
Anchor stores an 8-byte discriminator first, then the bytes needed for the
_rs`Counter`_ fields. The discriminator lets Anchor recognize this account as a
_rs`Counter`_ account before it deserializes the account data.

<CodePlaceholder title="initialize.rs" />

```rust !! title="initialize.rs"
#[derive(Accounts)]
pub struct Initialize<'info> {
    #[account(mut)]
    pub payer: Signer<'info>,
    #[account(
        init,
        payer = payer,
        // !focus
        space = 8 + Counter::INIT_SPACE,
        seeds = [COUNTER_SEED],
        bump
    )]
    pub counter: Account<'info, Counter>,
    pub system_program: Program<'info, System>,
}
```

## !!steps Counter Address

The _rs`seeds`_ and _rs`bump`_ constraints define the expected PDA address for
the counter account. Anchor verifies that the provided _rs`counter`_ account
matches that address. The template uses a PDA so users can derive the counter
address from the program ID and seed, making the counter address deterministic.

<CodePlaceholder title="initialize.rs" />

```rust !! title="initialize.rs"
#[derive(Accounts)]
pub struct Initialize<'info> {
    #[account(mut)]
    pub payer: Signer<'info>,
    #[account(
        init,
        payer = payer,
        space = 8 + Counter::INIT_SPACE,
        // !focus(1:2)
        seeds = [COUNTER_SEED],
        bump
    )]
    pub counter: Account<'info, Counter>,
    pub system_program: Program<'info, System>,
}
```

## !!steps System Program

The _rs`system_program`_ account is required because creating a new account uses
the System Program.

<CodePlaceholder title="initialize.rs" />

```rust !! title="initialize.rs"
#[derive(Accounts)]
pub struct Initialize<'info> {
    #[account(mut)]
    pub payer: Signer<'info>,
    #[account(
        init,
        payer = payer,
        space = 8 + Counter::INIT_SPACE,
        seeds = [COUNTER_SEED],
        bump
    )]
    pub counter: Account<'info, Counter>,
    // !focus
    pub system_program: Program<'info, System>,
}
```

## !!steps Handler Function

The _rs`handle_initialize`_ function runs after Anchor validates the accounts in
_rs`Initialize`_. The _rs`ctx`_ value gives the handler access to those checked
accounts.

<CodePlaceholder title="initialize.rs" />

```rust !! title="initialize.rs"
#[derive(Accounts)]
pub struct Initialize<'info> {
    #[account(mut)]
    pub payer: Signer<'info>,
    #[account(
        init,
        payer = payer,
        space = 8 + Counter::INIT_SPACE,
        seeds = [COUNTER_SEED],
        bump
    )]
    pub counter: Account<'info, Counter>,
    pub system_program: Program<'info, System>,
}

// !focus
pub fn handle_initialize(ctx: Context<Initialize>) -> Result<()> {
    ctx.accounts.counter.count = 0;
    ctx.accounts.counter.authority = ctx.accounts.payer.key();

    let cpi_accounts = anchor_lang::system_program::Transfer {
        from: ctx.accounts.payer.to_account_info(),
        to: ctx.accounts.counter.to_account_info(),
    };
    let cpi_ctx = CpiContext::new(anchor_lang::system_program::ID, cpi_accounts);
    anchor_lang::system_program::transfer(cpi_ctx, HELLO_WORLD_LAMPORTS)?;

    msg!("Hello, world! Counter initialized");
    Ok(())
}
```

## !!steps Initial Data

The handler writes the first values into the new counter account. The count
starts at _rs`0`_, and the payer becomes the authority allowed to increment the
counter later.

<CodePlaceholder title="initialize.rs" />

```rust !! title="initialize.rs"
#[derive(Accounts)]
pub struct Initialize<'info> {
    #[account(mut)]
    pub payer: Signer<'info>,
    #[account(
        init,
        payer = payer,
        space = 8 + Counter::INIT_SPACE,
        seeds = [COUNTER_SEED],
        bump
    )]
    pub counter: Account<'info, Counter>,
    pub system_program: Program<'info, System>,
}

pub fn handle_initialize(ctx: Context<Initialize>) -> Result<()> {
    // !focus(1:2)
    ctx.accounts.counter.count = 0;
    ctx.accounts.counter.authority = ctx.accounts.payer.key();

    let cpi_accounts = anchor_lang::system_program::Transfer {
        from: ctx.accounts.payer.to_account_info(),
        to: ctx.accounts.counter.to_account_info(),
    };
    let cpi_ctx = CpiContext::new(anchor_lang::system_program::ID, cpi_accounts);
    anchor_lang::system_program::transfer(cpi_ctx, HELLO_WORLD_LAMPORTS)?;

    msg!("Hello, world! Counter initialized");
    Ok(())
}
```

## !!steps Transfer Accounts

This transfer CPI is included only to demonstrate how a CPI passes accounts to
another program. The _rs`Transfer`_ struct lists the accounts used by the System
Program transfer.

<CodePlaceholder title="initialize.rs" />

```rust !! title="initialize.rs"
#[derive(Accounts)]
pub struct Initialize<'info> {
    #[account(mut)]
    pub payer: Signer<'info>,
    #[account(
        init,
        payer = payer,
        space = 8 + Counter::INIT_SPACE,
        seeds = [COUNTER_SEED],
        bump
    )]
    pub counter: Account<'info, Counter>,
    pub system_program: Program<'info, System>,
}

pub fn handle_initialize(ctx: Context<Initialize>) -> Result<()> {
    ctx.accounts.counter.count = 0;
    ctx.accounts.counter.authority = ctx.accounts.payer.key();

    // !focus(1:4)
    let cpi_accounts = anchor_lang::system_program::Transfer {
        from: ctx.accounts.payer.to_account_info(),
        to: ctx.accounts.counter.to_account_info(),
    };
    let cpi_ctx = CpiContext::new(anchor_lang::system_program::ID, cpi_accounts);
    anchor_lang::system_program::transfer(cpi_ctx, HELLO_WORLD_LAMPORTS)?;

    msg!("Hello, world! Counter initialized");
    Ok(())
}
```

## !!steps CPI Context

_rs`CpiContext::new`_ combines the program being called with the accounts passed
to that program. This is the basic shape of a CPI: choose the program to invoke,
collect the accounts that program expects, then pass both into the invocation.
Here, the program being called is the System Program.

<CodePlaceholder title="initialize.rs" />

```rust !! title="initialize.rs"
#[derive(Accounts)]
pub struct Initialize<'info> {
    #[account(mut)]
    pub payer: Signer<'info>,
    #[account(
        init,
        payer = payer,
        space = 8 + Counter::INIT_SPACE,
        seeds = [COUNTER_SEED],
        bump
    )]
    pub counter: Account<'info, Counter>,
    pub system_program: Program<'info, System>,
}

pub fn handle_initialize(ctx: Context<Initialize>) -> Result<()> {
    ctx.accounts.counter.count = 0;
    ctx.accounts.counter.authority = ctx.accounts.payer.key();

    let cpi_accounts = anchor_lang::system_program::Transfer {
        from: ctx.accounts.payer.to_account_info(),
        to: ctx.accounts.counter.to_account_info(),
    };
    // !focus
    let cpi_ctx = CpiContext::new(anchor_lang::system_program::ID, cpi_accounts);
    anchor_lang::system_program::transfer(cpi_ctx, HELLO_WORLD_LAMPORTS)?;

    msg!("Hello, world! Counter initialized");
    Ok(())
}
```

## !!steps Invoke Transfer

_rs`anchor_lang::system_program::transfer`_ invokes the System Program transfer
instruction. In this template, the transfer is a small example of calling
another program from your program. If the transfer CPI fails, the
_rs`initialize`_ instruction fails as well.

<CodePlaceholder title="initialize.rs" />

```rust !! title="initialize.rs"
#[derive(Accounts)]
pub struct Initialize<'info> {
    #[account(mut)]
    pub payer: Signer<'info>,
    #[account(
        init,
        payer = payer,
        space = 8 + Counter::INIT_SPACE,
        seeds = [COUNTER_SEED],
        bump
    )]
    pub counter: Account<'info, Counter>,
    pub system_program: Program<'info, System>,
}

pub fn handle_initialize(ctx: Context<Initialize>) -> Result<()> {
    ctx.accounts.counter.count = 0;
    ctx.accounts.counter.authority = ctx.accounts.payer.key();

    let cpi_accounts = anchor_lang::system_program::Transfer {
        from: ctx.accounts.payer.to_account_info(),
        to: ctx.accounts.counter.to_account_info(),
    };
    let cpi_ctx = CpiContext::new(anchor_lang::system_program::ID, cpi_accounts);
    // !focus
    anchor_lang::system_program::transfer(cpi_ctx, HELLO_WORLD_LAMPORTS)?;

    msg!("Hello, world! Counter initialized");
    Ok(())
}
```

## !!steps Log Message

_rs`msg!`_ writes a message to the program logs. _rs`Ok(())`_ indicates the
instruction returned successfully.

<CodePlaceholder title="initialize.rs" />

```rust !! title="initialize.rs"
#[derive(Accounts)]
pub struct Initialize<'info> {
    #[account(mut)]
    pub payer: Signer<'info>,
    #[account(
        init,
        payer = payer,
        space = 8 + Counter::INIT_SPACE,
        seeds = [COUNTER_SEED],
        bump
    )]
    pub counter: Account<'info, Counter>,
    pub system_program: Program<'info, System>,
}

pub fn handle_initialize(ctx: Context<Initialize>) -> Result<()> {
    ctx.accounts.counter.count = 0;
    ctx.accounts.counter.authority = ctx.accounts.payer.key();

    let cpi_accounts = anchor_lang::system_program::Transfer {
        from: ctx.accounts.payer.to_account_info(),
        to: ctx.accounts.counter.to_account_info(),
    };
    let cpi_ctx = CpiContext::new(anchor_lang::system_program::ID, cpi_accounts);
    anchor_lang::system_program::transfer(cpi_ctx, HELLO_WORLD_LAMPORTS)?;

    // !focus(1:2)
    msg!("Hello, world! Counter initialized");
    Ok(())
}
```

</ScrollyCoding>

### !imports

This file imports the shared constants and the _rs`Counter`_ account type. The
instruction uses those definitions to derive the PDA, choose the transfer
amount, and allocate the account with the right data size.

### !accountsStruct

_rs`Initialize`_ is the account context for the _rs`initialize`_ instruction.
Each field in the struct represents a separate account that must be included
when the instruction is called. Anchor uses the struct to validate those
incoming accounts before the handler runs.

### !payerMutable

_rs`#[account(mut)]`_ tells Anchor the payer account must be writable. This is
required because account creation and the transfer CPI both deduct lamports from
the payer.

### !payerSigner

_rs`Signer<'info>`_ tells Anchor the payer must sign the transaction.

### !counterConstraints

The _rs`#[account(...)]`_ block tells Anchor how to create and validate the
counter account before the handler runs.

### !initConstraint

_rs`init`_ tells Anchor to create the _rs`counter`_ account before the handler
runs. The new account is owned by this program so this program can store
_rs`Counter`_ data in it.

### !payerConstraint

_rs`payer = payer`_ specifies the _rs`payer`_ account as the payer for creating
the new counter account.

### !space

_rs`space = 8 + Counter::INIT_SPACE`_ allocates bytes for Anchor's account
discriminator plus the _rs`Counter`_ fields from `state.rs`. The discriminator
helps Anchor confirm the account stores the expected type before reading it.

### !seeds

_rs`seeds = [COUNTER_SEED]`_ says the counter account address must be the PDA
derived from this seed and the program ID. With one fixed seed, there is one
counter PDA for this program. To create separate counters in a real program, you
would usually add another seed such as a user's address.

### !bump

_rs`bump`_ tells Anchor to find and validate the PDA bump, which is the extra
byte that makes the derived address valid as a PDA.

### !counterAccountType

_rs`Account<'info, Counter>`_ tells Anchor to treat the account data as the
_rs`Counter`_ type from `state.rs`. Anchor also checks that the account is owned
by this program.

### !systemProgram

_rs`Program<'info, System>`_ requires the caller to provide the System Program.
Anchor uses it for the _rs`init`_ account creation constraint. The handler's
transfer CPI also invokes the System Program.

### !handler

The handler runs after Anchor validates the accounts and creates the counter
account, so it can safely write the account's initial data.

### !initialCount

Sets the _rs`count`_ field in the counter account to _rs`0`_.

### !initialAuthority

Sets the _rs`authority`_ field in the counter account to the payer's address.

### !cpiAccounts

These are the accounts passed to the System Program transfer instruction. This
transfer CPI is included only to demonstrate how a CPI passes accounts to
another program.

### !cpiContext

_rs`CpiContext`_ packages the target program and required accounts for a
cross-program invocation. Creating the context prepares the CPI by pairing the
program you want to call with the accounts that program expects.

### !transfer

This CPI invokes the System Program's transfer instruction and moves
_rs`HELLO_WORLD_LAMPORTS`_ from the payer to the counter account.

### !programLog

_rs`msg!`_ writes a message to the program logs when the program is invoked.

</WithNotes>

### increment.rs

`increment.rs` defines the accounts required to update an existing counter
account. The handler checks that the signer is the stored authority, checks that
the count has not reached the specified _rs`MAX_COUNT`_, and then increments the
count.

<WithNotes>

```rust title="programs/my-program/src/instructions/increment.rs" -w
use anchor_lang::prelude::*;

use crate::{constants::*, error::ErrorCode, state::Counter};

// !tooltip[/derive\(Accounts\)/] incrementAccounts
#[derive(Accounts)]
pub struct Increment<'info> {
    #[account(
        // !tooltip[/mut/] counterMutable
        mut,
        // !tooltip[/seeds = \[COUNTER_SEED\]/] counterSeeds
        seeds = [COUNTER_SEED],
        // !tooltip[/bump/] counterBump
        bump
    )]
    // !tooltip[/Account<'info, Counter>/] incrementCounterAccountType
    pub counter: Account<'info, Counter>,
    // !tooltip[/Signer/] authoritySigner
    pub authority: Signer<'info>,
}

// !tooltip[/handle_increment/] incrementHandler
pub fn handle_increment(ctx: Context<Increment>) -> Result<()> {
    // !tooltip[/require_keys_eq!/] authorityCheck
    require_keys_eq!(
        ctx.accounts.counter.authority,
        ctx.accounts.authority.key(),
        ErrorCode::Unauthorized,
    );
    // !tooltip[/require!/] maxCheck
    require!(
        ctx.accounts.counter.count < MAX_COUNT,
        ErrorCode::CounterOverflow,
    );

    // !tooltip[/count \+= 1/] mutateCount
    ctx.accounts.counter.count += 1;
    // !tooltip[/msg!/] programLog
    msg!("Hello, world! Counter is now {}", ctx.accounts.counter.count);
    Ok(())
}
```

<ScrollyCoding>

## !!steps Account Context

The _rs`Increment`_ struct defines the accounts that must be included when a
user calls the _rs`increment`_ instruction. Anchor checks these accounts before
the handler runs.

<CodePlaceholder title="increment.rs" />

```rust !! title="increment.rs"
// !focus(1:2)
#[derive(Accounts)]
pub struct Increment<'info> {
    #[account(
        mut,
        seeds = [COUNTER_SEED],
        bump
    )]
    pub counter: Account<'info, Counter>,
    pub authority: Signer<'info>,
}
```

## !!steps Counter Account

The _rs`counter`_ account stores the _rs`Counter`_ data. The _rs`mut`_
constraint allows the handler to update the stored count, and the _rs`seeds`_
and _rs`bump`_ constraints verify the counter PDA address.

<CodePlaceholder title="increment.rs" />

```rust !! title="increment.rs"
#[derive(Accounts)]
pub struct Increment<'info> {
    // !focus(1:6)
    #[account(
        mut,
        seeds = [COUNTER_SEED],
        bump
    )]
    pub counter: Account<'info, Counter>,
    pub authority: Signer<'info>,
}
```

## !!steps Authority Signer

The _rs`authority`_ account must sign the transaction. The handler later checks
that this signer matches the authority stored in the counter account.

<CodePlaceholder title="increment.rs" />

```rust !! title="increment.rs"
#[derive(Accounts)]
pub struct Increment<'info> {
    #[account(
        mut,
        seeds = [COUNTER_SEED],
        bump
    )]
    pub counter: Account<'info, Counter>,
    // !focus
    pub authority: Signer<'info>,
}
```

## !!steps Handler Function

The _rs`handle_increment`_ function runs after Anchor validates the accounts in
_rs`Increment`_. The _rs`ctx`_ value gives the handler access to those checked
accounts.

<CodePlaceholder title="increment.rs" />

```rust !! title="increment.rs"
#[derive(Accounts)]
pub struct Increment<'info> {
    #[account(
        mut,
        seeds = [COUNTER_SEED],
        bump
    )]
    pub counter: Account<'info, Counter>,
    pub authority: Signer<'info>,
}

// !focus
pub fn handle_increment(ctx: Context<Increment>) -> Result<()> {
    require_keys_eq!(
        ctx.accounts.counter.authority,
        ctx.accounts.authority.key(),
        ErrorCode::Unauthorized,
    );
    require!(
        ctx.accounts.counter.count < MAX_COUNT,
        ErrorCode::CounterOverflow,
    );

    ctx.accounts.counter.count += 1;
    msg!("Hello, world! Counter is now {}", ctx.accounts.counter.count);
    Ok(())
}
```

## !!steps Authority Check

The first check makes sure the signer is allowed to update this counter. If the
signer's address does not match _rs`counter.authority`_, the instruction stops
with _rs`ErrorCode::Unauthorized`_. This demonstrates application-level
authorization: the program owns the counter data, but it implements a rule for
which signer may change that data.

<CodePlaceholder title="increment.rs" />

```rust !! title="increment.rs"
#[derive(Accounts)]
pub struct Increment<'info> {
    #[account(
        mut,
        seeds = [COUNTER_SEED],
        bump
    )]
    pub counter: Account<'info, Counter>,
    pub authority: Signer<'info>,
}

pub fn handle_increment(ctx: Context<Increment>) -> Result<()> {
    // !focus(1:5)
    require_keys_eq!(
        ctx.accounts.counter.authority,
        ctx.accounts.authority.key(),
        ErrorCode::Unauthorized,
    );
    require!(
        ctx.accounts.counter.count < MAX_COUNT,
        ErrorCode::CounterOverflow,
    );

    ctx.accounts.counter.count += 1;
    msg!("Hello, world! Counter is now {}", ctx.accounts.counter.count);
    Ok(())
}
```

## !!steps Max Count Check

The second check keeps the counter from going past _rs`MAX_COUNT`_. If the
counter is already at the limit, the instruction stops with
_rs`ErrorCode::CounterOverflow`_. This limit is an artificial rule in the
template so you can see how custom errors stop an instruction before account
data is changed.

<CodePlaceholder title="increment.rs" />

```rust !! title="increment.rs"
#[derive(Accounts)]
pub struct Increment<'info> {
    #[account(
        mut,
        seeds = [COUNTER_SEED],
        bump
    )]
    pub counter: Account<'info, Counter>,
    pub authority: Signer<'info>,
}

pub fn handle_increment(ctx: Context<Increment>) -> Result<()> {
    require_keys_eq!(
        ctx.accounts.counter.authority,
        ctx.accounts.authority.key(),
        ErrorCode::Unauthorized,
    );
    // !focus(1:4)
    require!(
        ctx.accounts.counter.count < MAX_COUNT,
        ErrorCode::CounterOverflow,
    );

    ctx.accounts.counter.count += 1;
    msg!("Hello, world! Counter is now {}", ctx.accounts.counter.count);
    Ok(())
}
```

## !!steps Update Count

Only after both checks pass does the handler update the account data. This line
adds one to the stored counter value.

<CodePlaceholder title="increment.rs" />

```rust !! title="increment.rs"
#[derive(Accounts)]
pub struct Increment<'info> {
    #[account(
        mut,
        seeds = [COUNTER_SEED],
        bump
    )]
    pub counter: Account<'info, Counter>,
    pub authority: Signer<'info>,
}

pub fn handle_increment(ctx: Context<Increment>) -> Result<()> {
    require_keys_eq!(
        ctx.accounts.counter.authority,
        ctx.accounts.authority.key(),
        ErrorCode::Unauthorized,
    );
    require!(
        ctx.accounts.counter.count < MAX_COUNT,
        ErrorCode::CounterOverflow,
    );

    // !focus
    ctx.accounts.counter.count += 1;
    msg!("Hello, world! Counter is now {}", ctx.accounts.counter.count);
    Ok(())
}
```

## !!steps Log Message

_rs`msg!`_ writes the updated count to the program logs. _rs`Ok(())`_ indicates
the instruction returned successfully.

<CodePlaceholder title="increment.rs" />

```rust !! title="increment.rs"
#[derive(Accounts)]
pub struct Increment<'info> {
    #[account(
        mut,
        seeds = [COUNTER_SEED],
        bump
    )]
    pub counter: Account<'info, Counter>,
    pub authority: Signer<'info>,
}

pub fn handle_increment(ctx: Context<Increment>) -> Result<()> {
    require_keys_eq!(
        ctx.accounts.counter.authority,
        ctx.accounts.authority.key(),
        ErrorCode::Unauthorized,
    );
    require!(
        ctx.accounts.counter.count < MAX_COUNT,
        ErrorCode::CounterOverflow,
    );

    ctx.accounts.counter.count += 1;
    // !focus(1:2)
    msg!("Hello, world! Counter is now {}", ctx.accounts.counter.count);
    Ok(())
}
```

</ScrollyCoding>

### !incrementAccounts

_rs`Increment`_ is the account context for the _rs`increment`_ instruction.
Anchor uses it to validate the mutable counter account and required signer.

### !counterMutable

_rs`mut`_ tells Anchor the counter account must be writable because the handler
updates the stored _rs`count`_ value.

### !counterSeeds

_rs`seeds = [COUNTER_SEED]`_ verifies that the provided counter account is the
PDA derived from this seed and the program ID.

### !counterBump

_rs`bump`_ tells Anchor to find and validate the PDA bump for the counter
account.

### !incrementCounterAccountType

_rs`Account<'info, Counter>`_ tells Anchor to deserialize the account data as
the _rs`Counter`_ type from `state.rs`. Anchor also checks that the account is
owned by this program.

### !authoritySigner

_rs`Signer`_ requires the authority's signature. The handler then compares this
signer's address to the authority stored in the counter account.

### !incrementHandler

The handler runs after Anchor validates the account list, checks ownership, and
deserializes the counter account.

### !authorityCheck

_rs`require_keys_eq!`_ compares two public keys and stops the instruction unless
the signer's address matches the authority stored in the counter account. This
is the template's application-level authorization rule.

### !maxCheck

_rs`require!`_ checks a boolean rule and stops the instruction with
_rs`CounterOverflow`_ if the counter has already reached _rs`MAX_COUNT`_. This
template rule demonstrates custom errors and failing before mutation.

### !mutateCount

Only after both checks pass does the handler update the counter account data. If
either check fails, the transaction fails and the account is not changed.

### !programLog

_rs`msg!`_ writes a message to the program logs when the program is invoked.

</WithNotes>

## Test file

`programs/my-program/tests/test_initialize.rs` is a Rust integration test. It
does not start a local validator. Instead, it loads the compiled `.so` file into
LiteSVM, builds transactions that call the program, and reads the counter
account after each transaction. The test builds instructions for a Solana
transaction by specifying the program ID of the program to invoke, providing
instruction data, and passing the required accounts.

<SideBySide>

### !left

```rust title="initialize.rs" -w
#[derive(Accounts)]
pub struct Initialize<'info> {
    #[account(mut)]
    // !mark
    // !mention initialize-payer
    pub payer: Signer<'info>,
    #[account(
        init,
        payer = payer,
        space = 8 + Counter::INIT_SPACE,
        seeds = [COUNTER_SEED],
        bump
    )]
    // !mark
    // !mention initialize-counter
    pub counter: Account<'info, Counter>,
    // !mark
    // !mention initialize-system-program
    pub system_program: Program<'info, System>,
}
```

```rust title="test_initialize.rs" -w
let instruction = Instruction::new_with_bytes(
    program_id,
    // !mention initialize-instruction-data
    &my_program::instruction::Initialize {}.data(),
    my_program::accounts::Initialize {
        // !mark
        // !mention initialize-payer
        payer: payer.pubkey(),
        // !mark
        // !mention initialize-counter
        counter,
        // !mark
        // !mention initialize-system-program
        system_program: system_program::ID,
    }
    .to_account_metas(None),
);
```

### !right

The _rs`Initialize`_ account context defines the accounts required by the
_rs`initialize`_ instruction. The test passes those same accounts to the
generated _rs`my_program::accounts::Initialize`_ helper:

- [_rs`payer`_](mention:initialize-payer) is passed as
  _rs`payer: payer.pubkey()`_.
- [_rs`counter`_](mention:initialize-counter) is passed as _rs`counter`_.
- [_rs`system_program`_](mention:initialize-system-program) is passed as
  _rs`system_program::ID`_.

[_rs`my_program::instruction::Initialize {}.data()`_](mention:initialize-instruction-data)
creates the instruction data. This is where instruction arguments would be
encoded, but this _rs`initialize`_ instruction does not require any arguments.

</SideBySide>

<SideBySide>

### !left

```rust title="increment.rs" -w
#[derive(Accounts)]
pub struct Increment<'info> {
    #[account(
        mut,
        seeds = [COUNTER_SEED],
        bump
    )]
    // !mark
    // !mention increment-counter
    pub counter: Account<'info, Counter>,
    // !mark
    // !mention increment-authority
    pub authority: Signer<'info>,
}
```

```rust title="test_initialize.rs" -w
let instruction = Instruction::new_with_bytes(
    program_id,
    // !mention increment-instruction-data
    &my_program::instruction::Increment {}.data(),
    my_program::accounts::Increment {
        // !mark
        // !mention increment-counter
        counter,
        // !mark
        // !mention increment-authority
        authority: payer.pubkey(),
    }
    .to_account_metas(None),
);
```

### !right

The _rs`Increment`_ account context defines the accounts required by the
_rs`increment`_ instruction. The test passes those same accounts to the
generated _rs`my_program::accounts::Increment`_ helper:

- [_rs`counter`_](mention:increment-counter) is passed as _rs`counter`_.
- [_rs`authority`_](mention:increment-authority) is passed as
  _rs`authority: payer.pubkey()`_.

[_rs`my_program::instruction::Increment {}.data()`_](mention:increment-instruction-data)
creates the instruction data. This is where instruction arguments would be
encoded, but this _rs`increment`_ instruction does not require any arguments.

</SideBySide>

<WithNotes>

```rust title="programs/my-program/tests/test_initialize.rs" -w
use {
    anchor_lang::{
        prelude::Pubkey,
        solana_program::{instruction::Instruction, system_program},
        AccountDeserialize, InstructionData, ToAccountMetas,
    },
    // !tooltip[/litesvm::LiteSVM/] litesvm
    litesvm::LiteSVM,
    solana_keypair::Keypair,
    solana_message::{Message, VersionedMessage},
    solana_signer::Signer,
    solana_transaction::versioned::VersionedTransaction,
};

#[test]
fn test_initialize() {
    // !tooltip[/let program_id/] setup
    let program_id = my_program::id();
    let payer = Keypair::new();
    // !tooltip[/Pubkey::find_program_address/] counterPda
    let counter = Pubkey::find_program_address(
        &[my_program::constants::COUNTER_SEED],
        &program_id,
    )
    .0;
    let mut svm = LiteSVM::new();
    // !tooltip[/include_bytes!/] programBytes
    let bytes = include_bytes!(concat!(
        env!("CARGO_TARGET_TMPDIR"),
        "/../deploy/my_program.so"
    ));
    // !tooltip[/svm.add_program/] addProgram
    svm.add_program(program_id, bytes).unwrap();
    svm.airdrop(&payer.pubkey(), 1_000_000_000).unwrap();

    // !tooltip[/let instruction/] testInstruction
    let instruction = Instruction::new_with_bytes(
        program_id,
        &my_program::instruction::Initialize {}.data(),
        my_program::accounts::Initialize {
            payer: payer.pubkey(),
            counter,
            system_program: system_program::ID,
        }
        .to_account_metas(None),
    );

    // !tooltip[/svm.latest_blockhash/] blockhash
    let blockhash = svm.latest_blockhash();
    // !tooltip[/Message::new_with_blockhash/] message
    let msg = Message::new_with_blockhash(&[instruction], Some(&payer.pubkey()), &blockhash);
    // !tooltip[/VersionedTransaction::try_new/] transaction
    let tx = VersionedTransaction::try_new(VersionedMessage::Legacy(msg), &[&payer]).unwrap();

    // !tooltip[/svm.send_transaction/] sendTx
    let res = svm.send_transaction(tx);
    assert!(res.is_ok());

    // !tooltip[/svm.get_account/] getCounter
    let counter_account = svm.get_account(&counter).unwrap();
    let mut data: &[u8] = &counter_account.data;
    // !tooltip[/Counter::try_deserialize/] deserialize
    let counter_state = my_program::state::Counter::try_deserialize(&mut data).unwrap();
    // !tooltip[/assert_eq!\(counter_state.count, 0\)/] initAssert
    assert_eq!(counter_state.count, 0);
    assert_eq!(counter_state.authority, payer.pubkey());

    // !tooltip[/let instruction/] testInstruction
    let instruction = Instruction::new_with_bytes(
        program_id,
        &my_program::instruction::Increment {}.data(),
        my_program::accounts::Increment {
            counter,
            authority: payer.pubkey(),
        }
        .to_account_metas(None),
    );

    // !tooltip[/svm.latest_blockhash/] blockhash
    let blockhash = svm.latest_blockhash();
    // !tooltip[/Message::new_with_blockhash/] message
    let msg = Message::new_with_blockhash(&[instruction], Some(&payer.pubkey()), &blockhash);
    // !tooltip[/VersionedTransaction::try_new/] transaction
    let tx = VersionedTransaction::try_new(VersionedMessage::Legacy(msg), &[&payer]).unwrap();

    // !tooltip[/svm.send_transaction/] sendTx
    let res = svm.send_transaction(tx);
    assert!(res.is_ok());

    // !tooltip[/svm.get_account/] getCounter
    let counter_account = svm.get_account(&counter).unwrap();
    let mut data: &[u8] = &counter_account.data;
    // !tooltip[/Counter::try_deserialize/] deserialize
    let counter_state = my_program::state::Counter::try_deserialize(&mut data).unwrap();
    // !tooltip[/assert_eq!\(counter_state.count, 1\)/] incrementAssert
    assert_eq!(counter_state.count, 1);
    assert_eq!(counter_state.authority, payer.pubkey());
}
```

### !litesvm

_rs`LiteSVM`_ is an in-process Solana VM for tests. It lets the test register
the compiled program, create accounts, send transactions, and inspect account
state without starting a validator process.

### !setup

The test gets the program address from the _rs`declare_id!`_ value through
_rs`my_program::id()`_ and creates a new payer keypair for the test transaction.

### !counterPda

The counter address is derived from the same _rs`COUNTER_SEED`_ used by the
program. This makes the test target the PDA that `initialize.rs` expects.

### !programBytes

_rs`include_bytes!`_ reads the compiled `my_program.so` file produced by the
build. Those bytes are the executable program code that LiteSVM will run in the
test.

### !addProgram

_rs`svm.add_program`_ registers the compiled program bytes at the program
address in LiteSVM. The airdrop gives the payer enough local SOL to pay for the
transaction and account creation.

### !testInstruction

_rs`Instruction::new_with_bytes`_ creates an instruction to invoke the program.
It includes the program ID, instruction data, and instruction accounts.

### !blockhash

Every Solana transaction needs a recent blockhash. In this test, LiteSVM
provides a blockhash to use for the transaction.

### !message

The message contains the instruction, fee payer, and blockhash. This is the
transaction data that will be signed.

### !transaction

_rs`VersionedTransaction::try_new`_ signs the message with the payer keypair.
The payer signs because it pays the transaction fee and funds the new counter
account.

### !sendTx

_rs`svm.send_transaction`_ executes the transaction in LiteSVM.

### !getCounter

After the transaction runs, the test reads the counter account directly from
LiteSVM so it can inspect the account data.

### !deserialize

The counter account stores serialized data. _rs`Counter::try_deserialize`_
checks Anchor's account discriminator and turns the account data back into the
_rs`Counter`_ type from `state.rs`.

### !initAssert

After _rs`initialize`_ succeeds, the test deserializes the counter account and
checks that the starting state matches what _rs`handle_initialize`_ wrote.

### !incrementAssert

After _rs`increment`_ succeeds, the same counter account should have _rs`count`_
set to _rs`1`_ while keeping the same authority.

</WithNotes>

## Project configuration

The root project files tell Anchor and Cargo how to build, test, and deploy the
program. For a full reference, see the Anchor docs for
[Anchor.toml configuration](https://www.anchor-lang.com/docs/references/anchor-toml)
and the [Anchor CLI](https://www.anchor-lang.com/docs/references/cli).

<WithNotes>

```toml title="Anchor.toml"
# !tooltip[/skip_local_validator/] skipValidator
skip_local_validator = true

[toolchain]

[features]
resolution = true
skip-lint = false

# !tooltip[/programs.localnet/] programs
[programs.localnet]
my_program = "82sFkffP9wxwpyfZyeaKHH2chQoJPUGsJZSPi9mrUuXd"

# !tooltip[/provider/] provider
[provider]
cluster = "localnet"
wallet = "~/.config/solana/id.json"

# !tooltip[/scripts/] scripts
[scripts]
test = "cargo test"

[hooks]
```

### !skipValidator

`skip_local_validator = true` tells Anchor not to start a validator for
`anchor test`. The Rust test uses LiteSVM instead.

### !programs

`[programs.localnet]` maps the Rust crate name to the program address used for
local builds and tests.

### !provider

`[provider]` sets the default cluster and wallet for commands such as
`anchor deploy`.

### !scripts

`[scripts]` changes what `anchor test` runs. In this template, `anchor test`
runs `cargo test`.

</WithNotes>
