> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/solana-foundation/anchor/llms.txt
> Use this file to discover all available pages before exploring further.

# State Management

> Learn how to manage program state with account initialization, updates, and the

State management in Anchor programs involves creating, reading, updating, and closing accounts that store your program's data. Anchor provides powerful abstractions through the `#[account]` macro and account constraints to make state management safe and ergonomic.

## The #\[account] Macro

The `#[account]` macro is applied to structs to create custom account types for your program. It automatically implements several traits:

* **Owner**: Sets the account owner to the program ID (from `declare_id!`)
* **AccountSerialize** and **AccountDeserialize**: Handles serialization
* **Discriminator**: Adds an 8-byte discriminator to distinguish account types

### Basic Account Definition

```rust theme={null}
#[account]
pub struct MyAccount {
    pub data: u64,
    pub authority: Pubkey,
    pub created_at: i64,
}
```

The `#[account]` macro adds an 8-byte discriminator at the start, so when calculating space:

```rust theme={null}
// Space = 8 (discriminator) + account data size
space = 8 + 8 + 32 + 8  // discriminator + u64 + Pubkey + i64
```

## InitSpace Derive Macro

For easier space calculation, use the `InitSpace` derive macro:

```rust theme={null}
#[account]
#[derive(InitSpace)]
pub struct MyAccount {
    pub data: u64,
    pub authority: Pubkey,
    #[max_len(50)]
    pub name: String,
    #[max_len(10)]
    pub tags: Vec<u8>,
}

// Usage in accounts struct:
#[account(
    init,
    payer = authority,
    space = 8 + MyAccount::INIT_SPACE
)]
pub my_account: Account<'info, MyAccount>,
```

## Account Initialization

To create and initialize a new account, use the `init` constraint:

```rust theme={null}
#[derive(Accounts)]
pub struct Initialize<'info> {
    #[account(
        init,
        payer = user,
        space = 8 + MyAccount::INIT_SPACE
    )]
    pub my_account: Account<'info, MyAccount>,
    #[account(mut)]
    pub user: Signer<'info>,
    pub system_program: Program<'info, System>,
}
```

The `init` constraint:

* Creates the account via CPI to the system program
* Allocates the specified space
* Assigns ownership to your program
* Sets the account discriminator
* Requires `payer` and `space` parameters
* Requires `system_program` in the accounts struct

### Initialization with PDA

For PDA (Program Derived Address) accounts:

```rust theme={null}
#[derive(Accounts)]
pub struct InitializePda<'info> {
    #[account(
        init,
        payer = user,
        space = 8 + MyAccount::INIT_SPACE,
        seeds = [b"my_account", user.key().as_ref()],
        bump
    )]
    pub my_account: Account<'info, MyAccount>,
    #[account(mut)]
    pub user: Signer<'info>,
    pub system_program: Program<'info, System>,
}
```

## Reading Account Data

Access account data through the `Context`:

```rust theme={null}
pub fn read_data(ctx: Context<ReadData>) -> Result<()> {
    let account = &ctx.accounts.my_account;
    msg!("Data: {}", account.data);
    msg!("Authority: {}", account.authority);
    Ok(())
}

#[derive(Accounts)]
pub struct ReadData<'info> {
    pub my_account: Account<'info, MyAccount>,
}
```

## Updating Account Data

To modify account data, mark the account as `mut` (mutable):

```rust theme={null}
pub fn update_data(ctx: Context<UpdateData>, new_value: u64) -> Result<()> {
    let account = &mut ctx.accounts.my_account;
    account.data = new_value;
    msg!("Updated data to: {}", new_value);
    Ok(())
}

#[derive(Accounts)]
pub struct UpdateData<'info> {
    #[account(mut)]
    pub my_account: Account<'info, MyAccount>,
}
```

Anchor automatically serializes the account data back to the account when the instruction completes successfully.

## Account Constraints

Use constraints to enforce security and business logic:

### has\_one Constraint

Verifies that an account field matches a provided account:

```rust theme={null}
#[derive(Accounts)]
pub struct UpdateData<'info> {
    #[account(
        mut,
        has_one = authority
    )]
    pub my_account: Account<'info, MyAccount>,
    pub authority: Signer<'info>,
}
```

This checks that `my_account.authority == authority.key()`.

### constraint Constraint

Custom validation logic:

```rust theme={null}
#[derive(Accounts)]
pub struct UpdateData<'info> {
    #[account(
        mut,
        constraint = my_account.data < 100 @ ErrorCode::DataTooLarge
    )]
    pub my_account: Account<'info, MyAccount>,
}
```

## Closing Accounts

Reclaim SOL rent by closing accounts with the `close` constraint:

```rust theme={null}
pub fn close_account(ctx: Context<CloseAccount>) -> Result<()> {
    msg!("Closing account");
    Ok(())
}

#[derive(Accounts)]
pub struct CloseAccount<'info> {
    #[account(
        mut,
        close = authority,
        has_one = authority
    )]
    pub my_account: Account<'info, MyAccount>,
    #[account(mut)]
    pub authority: Signer<'info>,
}
```

The `close` constraint:

* Transfers all lamports to the specified account
* Zeroes out the account data
* Marks the account for garbage collection

## Reallocating Accounts

Increase or decrease account size with `realloc`:

```rust theme={null}
#[derive(Accounts)]
pub struct ReallocAccount<'info> {
    #[account(
        mut,
        realloc = 8 + MyAccount::INIT_SPACE + 100,
        realloc::payer = authority,
        realloc::zero = true,
    )]
    pub my_account: Account<'info, MyAccount>,
    #[account(mut)]
    pub authority: Signer<'info>,
    pub system_program: Program<'info, System>,
}
```

## Complete Example

Here's a complete counter program demonstrating state management:

```rust theme={null}
use anchor_lang::prelude::*;

declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS");

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

    pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
        let counter = &mut ctx.accounts.counter;
        counter.authority = ctx.accounts.authority.key();
        counter.count = 0;
        msg!("Counter initialized");
        Ok(())
    }

    pub fn increment(ctx: Context<Update>) -> Result<()> {
        let counter = &mut ctx.accounts.counter;
        counter.count = counter.count.checked_add(1)
            .ok_or(ErrorCode::Overflow)?;
        msg!("Counter: {}", counter.count);
        Ok(())
    }

    pub fn decrement(ctx: Context<Update>) -> Result<()> {
        let counter = &mut ctx.accounts.counter;
        counter.count = counter.count.checked_sub(1)
            .ok_or(ErrorCode::Underflow)?;
        msg!("Counter: {}", counter.count);
        Ok(())
    }

    pub fn close(ctx: Context<Close>) -> Result<()> {
        msg!("Counter closed");
        Ok(())
    }
}

#[derive(Accounts)]
pub struct Initialize<'info> {
    #[account(
        init,
        payer = authority,
        space = 8 + Counter::INIT_SPACE,
        seeds = [b"counter", authority.key().as_ref()],
        bump
    )]
    pub counter: Account<'info, Counter>,
    #[account(mut)]
    pub authority: Signer<'info>,
    pub system_program: Program<'info, System>,
}

#[derive(Accounts)]
pub struct Update<'info> {
    #[account(
        mut,
        has_one = authority
    )]
    pub counter: Account<'info, Counter>,
    pub authority: Signer<'info>,
}

#[derive(Accounts)]
pub struct Close<'info> {
    #[account(
        mut,
        close = authority,
        has_one = authority
    )]
    pub counter: Account<'info, Counter>,
    #[account(mut)]
    pub authority: Signer<'info>,
}

#[account]
#[derive(InitSpace)]
pub struct Counter {
    pub authority: Pubkey,
    pub count: u64,
}

#[error_code]
pub enum ErrorCode {
    #[msg("Counter overflow")]
    Overflow,
    #[msg("Counter underflow")]
    Underflow,
}
```

## init\_if\_needed

For accounts that might already exist, use `init_if_needed`:

```rust theme={null}
#[account(
    init_if_needed,
    payer = user,
    space = 8 + MyAccount::INIT_SPACE
)]
pub my_account: Account<'info, MyAccount>,
```

<Callout type="warning">
  Be careful with `init_if_needed` as it can introduce security vulnerabilities if not used properly. Always validate the account state after initialization.
</Callout>

## Best Practices

1. **Use InitSpace**: Leverage `#[derive(InitSpace)]` for automatic space calculation
2. **Validate ownership**: Always use `has_one` or other constraints to verify account relationships
3. **Check arithmetic**: Use checked math operations to prevent overflows
4. **Close unused accounts**: Reclaim rent by closing accounts when done
5. **Use PDAs for deterministic addresses**: Prefer PDAs over keypair-based accounts
6. **Minimize account size**: Only store necessary data to reduce rent costs

## Related Resources

* [Account Constraints Reference](/api/rust/account-constraints)
* [Account Types Reference](/api/rust/account-types)
* [Program Derived Addresses](/concepts/pda)
