Anchor is recommended for beginners in all of the docs and guides.

The purpose of this guide is to elucidate how Rust development on Solana works without Anchor, so you can understand what's going on under the hood, as well as appreciate the conveniences Anchor provides.

This article goes over what's obscured from you when using Anchor, and what really happens underneath. We'll go over some docs examples of a simple counter program between raw Solana and Anchor.

## Transactions and Instructions

The basic operating unit in Solana is an `instruction`, which are held in `transactions` which are their atomic, all or nothing counterpart.

Instructions hold three things:

1. an array of accounts,
2. the `program_id` that the transaction is targeting,
3. as well as `instruction_data` which is stored as an array of `u8` integers.

Why is `instruction_data` a bunch of `u8`?

Each of these numbers is one byte (8 bits) of the data stored in the instruction. These bytes will be decoded by your program to get the actual data. This data represents the actions the client wants to take with the program.

The client will create data structures (often Structs in Rust) and serialize them into this array of bytes, which the receiving program will then deserialize and make sense of.

Without Anchor, there's no real convention to this. It's up to the developer which serialization/deserialization strategy to use. This gives unlimited flexibility but makes it harder to read/write instructions when no convention is followed.

Let's look at the example Solana gives for their basic Rust program:

```rust
use solana_program::{
    account_info::AccountInfo, entrypoint, entrypoint::ProgramResult, msg, pubkey::Pubkey,
};

entrypoint!(process_instruction);

pub fn process_instruction(
    _program_id: &Pubkey,
    _accounts: &[AccountInfo],
    _instruction_data: &[u8],
) -> ProgramResult {
    msg!("Hello, world!");
    Ok(())
}
```

All Solana programs have a single entrypoint defined by the `entrypoint!` macro.

Here's what a client to this program would look like in a test:

```rust
#[cfg(test)]
mod test {
    use solana_program_test::*;
    use solana_sdk::{
        instruction::Instruction,
        pubkey::Pubkey,
        signature::Signer,
        transaction::Transaction,
    };

#[tokio::test]
    async fn test_hello_world() {
        let program_id = Pubkey::new_unique();
        let mut program_test = ProgramTest::default();

program_test.add_program("hello_world", program_id, None);

let (mut banks_client, payer, recent_blockhash) = program_test.start().await;

// Create instruction
        let instruction = Instruction {
            program_id,
            accounts: vec![],
            data: vec![],
        };

// Create transaction with instruction
        let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey()));

// Sign transaction
        transaction.sign(&[&payer], recent_blockhash);

let transaction_result = banks_client.process_transaction(transaction).await;
        assert!(transaction_result.is_ok());
    }
}
```

Here we manually create the `Instruction` and `Transaction`, and run that transaction through the `banks_client` which simulates the Solana runtime and runs it in-memory.

The banks client is a special type of client used only for testing. It's not as powerful as simulating with a real client but is useful for quickly simulating a certain state on the blockchain before your test runs.

For a deeper look at how a real `program` would deserialize and parse the transaction data, see [their example](https://solana.com/docs/programs/rust/program-structure#example-program).

### Instructions in anchor

Now let's take a look at similar Anchor examples and break down what's happening.

```rust
use anchor_lang::prelude::*;

declare_id!("6khKp4BeJpCjBY1Eh39ybiqbfRnrn2UzWeUARjQLXYRC");

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

pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
        let counter = &ctx.accounts.counter;
        msg!("Counter account created! Current count: {}", counter.count);
        Ok(())
    }

pub fn increment(ctx: Context<Increment>) -> Result<()> {
        let counter = &mut ctx.accounts.counter;
        msg!("Previous counter: {}", counter.count);

counter.count += 1;
        msg!("Counter incremented! Current count: {}", counter.count);
        Ok(())
    }
}
```

What is this `Context` that seems to have super powers?

In Anchor, a lot of the lower down concepts like `Transaction` and `Instruction` get abstracted away. Instead we get a very declarative experience powered by macros, which do a ton of heavy lifting.

For example, what does a line like the one below do?

```rust
pub fn initialize(ctx: Context<Initialize>) -> Result<()> 
```

We're telling Anchor that we want to use a set of account constraints via the `Initialize` struct. We want it to auto-validate the constraints before running any logic.

Every Solana program is stateless, all state is passed in via accounts which act as buffers of data. They hold the state your program is acting on.

`Context` wraps our structs and provides the additional metadata and checks for things like access control (can this person send this SOL?) and validations.

The `Initialize` struct itself will `#[derive(Accounts)]` which will implement important traits for handling serialization, deserialization and validations on the types of accounts we can pass the program.

```rust
#[derive(Accounts)]
pub struct Initialize<'info> {
    #[account(mut)]
    pub payer: Signer<'info>,

#[account(
        init,
        payer = payer,
        space = 8 + 8
    )]
    pub counter: Account<'info, Counter>,
    pub system_program: Program<'info, System>,
}
```

In this struct we're telling Anchor to apply constraints to these accounts.

- The `#[account(mut)]` line tells Anchor to ensure that the `payer` account MUST be mutable, because we're going to be extracting rent from it.
- The `Signer<'info>` portion tells Anchor that this account must sign the transaction.

The `#[account(init, payer = payer, space = 8 + 8)]` line tells Anchor a few things:

1. First the `init` argument tells Anchor that it will be creating this account.
2. The next line says to use the `payer` account to fund it. Whereas the `space` argument tells Anchor to reserve 8 bytes for the `discriminator` (bytes that reflect the type of the following set of bytes), and 8 additional bytes for tracking the state of the `u64` counter used in the example.
3. Finally, the line `pub system_program: Program<'info, System>` is necessary to call `system_instruction::create_account` later in the code, as well as acting as a validator that the program is actually the correct program (by checking the ID).

So, `Context` is a wrapper around the accounts that are required to run a given instruction, say for `initialize` or `increment`.

We're also telling it to automatically deserialize the account data (ex. `Account<'info, Counter>`) so we can avoid manually translating from the bytes to a struct using `borsh`, `serde` or similar like we have to do in plain old Solana development.

```rust
#[derive(Accounts)]
pub struct Increment<'info> {
    #[account(mut)]
    pub counter: Account<'info, Counter>,
}
```

Here we are telling anchor that the account we pass in the `counter` slot is going to deserialize into a `Counter` struct.

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

So to sum it up, you can think of the `#derive(Accounts)` and `#[account(...)]` macros as defining the structure and validation logic that Anchor uses to build the `Context<T>` at runtime.

In essence they provide:

- Validators (is it mutable? does it sign?)
- Instruction directives (initialize this account, use this payer)
- Security checks (ownership, seeds, constraints, etc.)

By providing this information up-front on the `program`, Anchor is able to construct [IDLs](/content/solana/understanding_idl/index.html), which provide a schema to work with as a `client`.

> Okay that's great that Context provides so much utility, but where are my Instructions?

This is where the IDL ties into everything, and is where we take a look at a `client` in Anchor.

Inside the `client` code we would find a line like this:

```rust
declare_program!(something);
```

This macro does a lot of heavy lifting, and will generate the client for us automatically.

Take for an example this snippet which initializes an account:

```rust
let initialize_ix = program
    .request()
    .accounts(accounts::Initialize {
        counter: counter.pubkey(),
        payer: program.payer(),
        system_program: system_program::ID,
    })
    .args(args::Initialize)
    .instructions()? 
    .remove(0);
```

It's the IDL that gives us the `accounts::Initialize {}` struct.

So while we don't see any explicit/manual handling of `Instruction` and `Transaction` like we do in plain old Solana, Anchor instead is providing us the structs we need to use to interact with the program, and the parsing into Instructions and the greater Transaction is done automatically and without boilerplate.
