declare_id!: Specifies the program’s on-chain address#[program]: Specifies the module containing the program’s instruction logic#[derive(Accounts)]: Applied to structs to indicate a list of accounts required by an instruction#[account]: Applied to structs to create custom account types for the program
Example program
Let’s examine a simple program that demonstrates the usage of the macros mentioned above to understand the basic structure of an Anchor program. The program below includes a single instruction calledinitialize that creates a new account (NewAccount) and initializes it with a u64 value.
declare_id! macro
Thedeclare_id! macro specifies the on-chain address of the program, known as the program ID.
/target/deploy/your_program_name.json.
To update the value of the program ID in the declare_id macro with the public key of the keypair in the /target/deploy/your_program_name.json file, run:
anchor keys sync command is useful when cloning a repository where the program ID in the declare_id macro won’t match the one generated when you run anchor build locally.
#[program] attribute
The#[program] attribute annotates the module containing all the instruction handlers for your program. Each public function within this module corresponds to an instruction that can be invoked.
Instruction parameters
Each instruction handler takes:- Context: First parameter is always
Context<T>containing validated accounts - Additional parameters: Any additional instruction parameters
Context<T> type provides access to:
accounts: The validated accountsprogram_id: The program’s IDremaining_accounts: Any additional accounts not specified in the#[derive(Accounts)]structbumps: PDA bump seeds for accounts usingseedsconstraint
#[derive(Accounts)] macro
The#[derive(Accounts)] macro is applied to structs to define the list of accounts required by an instruction.
Account constraints
Account constraints specify security checks and requirements:init: Initialize a new accountmut: Mark account as mutablepayer: Specify who pays for account creationspace: Required space for the accountseedsandbump: For PDA validationhas_one: Check account fields matchconstraint: Custom validation logic
#[account] attribute
The#[account] attribute is applied to structs to create custom account types that can be used with Anchor programs.
- Implements
AccountSerializeandAccountDeserializetraits - Adds an 8-byte discriminator to identify the account type
- Implements the
Ownertrait to ensure the account is owned by the program
Space calculation
When creating accounts, you need to calculate the required space:InitSpace derive macro to automatically calculate space:
Complete example
Here’s a complete counter program demonstrating all the key components:Next steps
Accounts
Learn about account types and validation
Instructions
Deep dive into instruction handlers