# A deep dive into the basic-1 anchor example

By [Camden](https://paragraph.com/@camden) · 2021-10-26

---

Today we'll be going over the basic-1 anchor example, doing a deep dive of why everything is the way it is. This will cover new ground, including the addition of

Other editions: [basic-0](https://mirror.xyz/0x840B1dC2abb99f1F86D549303719610F346B2aaF/w3-WcRd8aablvFf8Er5qH4H4b-x-8UVfhElMv6Uwick) deep dive.

You'll also need the [prerequisites found here](https://project-serum.github.io/anchor/getting-started/installation.html). I'm basically re-creating the tutorial found [here](https://project-serum.github.io/anchor/tutorials/tutorial-1.html).

Getting started
---------------

To get started, clone the repo and go to the example.

    git clone https://github.com/project-serum/anchor
    cd anchor/examples/tutorial/basic-1
    

High-level components
---------------------

This example has two high-level components, the program itself (at `programs/basic-1/src/lib.rs`) and the integration tests (found at `tests/basic-1.js`).

We'll be treating this example here as if we were doing local development, using the integration tests to iterate quickly.

Dive in
-------

Let's dive in immediately and run

    # Ensure you don't have solana-test-validator running!
    anchor test
    

We should see the following output:

      basic-1
        ✔ Creates and initializes an account in a single atomic transaction (simplified) (143ms)
        ✔ Updates a previously created account (411ms)
    
    
      2 passing (557ms)
    

Our tests are currently passing, as expected!

Let's dive in to the program and use the integration tests as a tool to see what changing different pieces of the program would do.

The account struct
------------------

    #[account]
    pub struct MyAccount {
        pub data: u64,
    }
    

This struct defines what shape the account data will have. This specific account will be a struct with a field `data` of type `u64`.

Try removing the `#[account]` attribute and re-running `anchor test`.

    ... snip ...
    
    error[E0277]: the trait bound `MyAccount: Clone` is not satisfied
      --> programs/basic-1/src/lib.rs:34:21
       |
    34 |     pub my_account: Account<'info, MyAccount>,
       |                     ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `MyAccount`
       |
      ::: /home/camden/anchor/lang/src/account.rs:12:78
       |
    12 | pub struct Account<'info, T: AccountSerialize + AccountDeserialize + Owner + Clone> {
       |                                                                              ----- required by this bound in `anchor_lang::Account`
    

When we define an Account, the associated account data type must have these traits. The important thing here is that any account struct must have the `#[account]` attribute so Anchor knows how to work with that struct.

Add back the `#[account]` attribute before continuing.

### Allocating space

Let's add in a new field on the struct now:

    #[account]
    pub struct MyAccount {
        pub data: u64,
        pub another_data: u64,
    }
    

Then run `anchor test`

    ... snip ...
    
      logs: [
        'Program Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS invoke [1]',
        'Program 11111111111111111111111111111111 invoke [2]',
        'Program 11111111111111111111111111111111 success',
        'Program log: Custom program error: 0xa3',
        'Program Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS consumed 9553 of 200000 compute units',
        'Program Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS failed: custom program error: 0xa3'
      ]
    }
        1) Creates and initializes an account in a single atomic transaction (simplified)
        2) Updates a previously created account
    
    
      0 passing (67ms)
      2 failing
    
    ... snip ...
    

Our logs from invoking Solana aren't super helpul here. We definitely reached the system program (11....11) but we failed to initialize.

There aren't a ton of good clues here, but what did we actually change? We added another field to the struct, which ends up increasing the amount of space we need.

The fix here is to look above to where it says `space = 8 + 8`. We can change that to `space = 8 + 8 + 8`, and run `anchor test` again, which will pass.

What did we learn? We have to be careful about the space we allocate for our account data and make sure that we allocate the right amount of space. We have to allocate 8 bytes for the discrimnator, 8 bytes for data, and 8 bytes for another\_data.

Let's revert the changes we've made up to this point.

The Initialize accounts
-----------------------

The initialize accounts are defined here:

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

Solana requires that we specify _all_ the accounts that are used in the instruction handler because validators need to be able to operate on many accounts in parallel. Getting a mutable reference to an account will rqeuire blocking on any further changes to that account.

The system program account
--------------------------

If you look at the Initialize handler above, you'll notice that the system_program account is never explicitly used. However, try removing the system_program and the program won't compile. That's because we've defined, in this struct, `my_account` as an account that is to be initialized. As a result, anchor requires us to include the system_program because the system_program is the program capable of initializing accounts.

If we look at the Update accounts, we'll see that there is no system_program defined. That is because we are just updating that account's data and not initalizing it, so anchor doesn't require us to have access to the system_program.

The user account
----------------

We also don't explicitly use the user account in the instruction handler for Initialize. Let's try removing it (along with the `#[account(mut)])` attribute).

This won't compile either. That's because the account that's paying for the rent is the user, so we'll get a compilation error.

#### Why does the user account have the mutable attribute?

Let's re-add the user account line, but leave off the `#[account(mut)]` piece. This compiles, so let's run `anchor test`.

This actually works. I don't know if anchor test isn't testing all the constraints we expect, but I don't think this would work in a client setting. My expectation would be that this doesn't work because the user account needs to be mutable for the program to debit the account to pay for the space allocation.

**Open question--don't quite get this...**

#### The Signer struct

The Signer struct just tells anchor that the user account has signed the transaction. Anchor knows that it doesn't have to fetch or deserialize the data associated with this account.

my\_account
-----------

Finally, we have the account that actually holds the data for our program.

We've already covered the pieces of the attribute that this is tagged with, so let's look at the account itself.

    pub my_account: Account<'info, MyAccount>
    

This tells anchor that we have an account here with data. Anchor should expect to deserialize the data into a MyAccount object, which we already went over.

The Update accounts
-------------------

Very simply, the Update instruction only requires one account, which is the original account that we stored the data in. This has the mutable attribute, because we want to be able to update the account data.

The instruction handlers
------------------------

Finally, we can move on to the instruction handlers!

These are virtually identical in how they are implemented in the code. They both take two parameters, take a mutable reference to my\_account, and then update the data.

What happens under the hood is very different though, and the differences are entirely because of the different account specifications.

When we call initailize, anchor, under the hood, is making a call to the system program to initialize the account at my\_account's address. Only after initializing the account does it update the data.

The update instruction takes an already initailized account with this type of data and just updates it.

Note that we never have to "commit" our changes in any way. We use our mutable reference to the account's data and anchor will automatically update the account's data for us.

Thanks for reading this deep dive. I'll be continuing to do more deep dives on these anchor examples.

---

*Originally published on [Camden](https://paragraph.com/@camden/a-deep-dive-into-the-basic-1-anchor-example)*
