| title | Local Development |
|---|---|
| description | Learn how to build Solana programs using the Anchor framework on your local machine. |
The Anchor framework is a tool that simplifies the process of building Solana programs. Whether you're new to blockchain development or an experienced programmer, Anchor simplifies the process of writing, testing, and deploying Solana programs.
In this section, we'll walk through:
- Creating a new Anchor project
- Building and testing your program
- Deploying to Solana clusters
- Understanding the project file structure
For detailed installation instructions, visit the installation page.
Before you begin, ensure you have the following installed:
- Rust: The programming language for building Solana programs.
- Solana CLI: Command-line tool for Solana development.
- Anchor CLI: Command-line tool for the Anchor framework.
To verify Anchor CLI installation, open your terminal and run:
anchor --versionExpected output:
anchor-cli 1.0.2This section covers the basic steps to create, build, and test your first local Anchor program.
To start a new project, use the anchor init command followed by your project's
name. This command creates a new directory with the specified name and sets up a
default program and test file.
anchor init my-projectNavigate to the new project directory and open it in your code editor.
cd my-projectBy default, Anchor generates a modular program structure to promote better code organization and maintainability. The program files are organized as follows:
/programs/my-project/src/lib.rs- Main entry point with module declarations/programs/my-project/src/instructions/- Instruction handlers/programs/my-project/src/state/- Account structures and state/programs/my-project/src/constants.rs- Program constants/programs/my-project/src/error.rs- Custom error definitions
The value in the declare_id! macro is the program ID, a unique identifier for
your program.
By default, it is the public key of the keypair generated in
/target/deploy/my_project-keypair.json.
Main entry point (lib.rs):
pub mod constants;
pub mod error;
pub mod instructions;
pub mod state;
use anchor_lang::prelude::*;
pub use constants::*;
pub use instructions::*;
pub use state::*;
declare_id!("3ynNB373Q3VAzKp7m4x238po36hjAGFXFJB4ybN2iTyg");
#[program]
pub mod my_project {
use super::*;
pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
initialize::handler(ctx)
}
}Instruction handler (instructions/initialize.rs):
use anchor_lang::prelude::*;
#[derive(Accounts)]
pub struct Initialize {}
pub fn handler(ctx: Context<Initialize>) -> Result<()> {
msg!("Greetings from: {:?}", ctx.program_id);
Ok(())
}For simpler projects or quick prototyping, you can use the single-file template
with anchor init --template single. However, the modular structure is
recommended for production code as it improves code organization, readability,
and maintainability.
The default Typescript test file is located at /tests/my-project.ts.
This file demonstrates how to invoke the default program's initialize
instruction in Typescript.
import * as anchor from "@anchor-lang/core";
import { Program } from "@anchor-lang/core";
import { MyProject } from "../target/types/my_project";
describe("my-project", () => {
// Configure the client to use the local cluster.
anchor.setProvider(anchor.AnchorProvider.env());
const program = anchor.workspace.MyProject as Program<MyProject>;
it("Is initialized!", async () => {
// Add your test here.
const tx = await program.methods.initialize().rpc();
console.log("Your transaction signature", tx);
});
});If you prefer Rust for testing, initialize your project with the
--test-template rust (Anchor Rust client) or
--test-template mollusk (Mollusk test library) flag.
anchor init --test-template rust my-programThe Rust test file will be at /tests/src/test_initialize.rs.
use std::str::FromStr;
use anchor_client::{
solana_sdk::{
commitment_config::CommitmentConfig, pubkey::Pubkey, signature::read_keypair_file,
},
Client, Cluster,
};
#[test]
fn test_initialize() {
let program_id = "3ynNB373Q3VAzKp7m4x238po36hjAGFXFJB4ybN2iTyg";
let anchor_wallet = std::env::var("ANCHOR_WALLET").unwrap();
let payer = read_keypair_file(&anchor_wallet).unwrap();
let client = Client::new_with_options(Cluster::Localnet, &payer, CommitmentConfig::confirmed());
let program_id = Pubkey::from_str(program_id).unwrap();
let program = client.program(program_id).unwrap();
let tx = program
.request()
.accounts(my_program::accounts::Initialize {})
.args(my_program::instruction::Initialize {})
.send()
.expect("");
println!("Your transaction signature {}", tx);
}Build the program by running anchor build.
anchor buildThe compiled program will be at /target/deploy/my_project.so. The content of
this file is what gets stored on the Solana network (as an executable account)
when you deploy your program.
To test the program, run anchor test.
anchor testBy default, the Anchor.toml config file specifies the localnet cluster. When
developing on localnet, anchor test will automatically:
- Start a local Solana validator
- Build and deploy your program to the local cluster
- Run the tests in the
testsfolder - Stop the local Solana validator
Alternatively, you can manually start a local Solana validator and run tests against it. This is useful if you want to keep the validator running while you iterate on your program. It allows you to inspect accounts and transaction logs on the Solana Explorer while developing locally.
Open a new terminal and start a local Solana validator by running the
solana-test-validator command.
solana-test-validatorIn a separate terminal, run the tests against the local cluster. Use the
--skip-local-validator flag to skip starting the local validator since it's
already running.
anchor test --skip-local-validatorBy default, the Anchor.toml config file in an Anchor project specifies the
localnet cluster.
[toolchain]
[features]
resolution = true
skip-lint = false
[programs.localnet]
my_program = "3ynNB373Q3VAzKp7m4x238po36hjAGFXFJB4ybN2iTyg"
[provider]
cluster = "Localnet"
wallet = "~/.config/solana/id.json"
[scripts]
test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts"To deploy your program to devnet, change the cluster value to Devnet.
Note that deploying to devnet requires your wallet to have enough SOL to cover deployment cost. You can get devnet SOL using the Web Faucet.
-cluster = "Localnet"
+cluster = "Devnet"[provider]
cluster = "Devnet"
wallet = "~/.config/solana/id.json"Now when you run anchor deploy, your program will be deployed to the devnet
cluster. The anchor test command will also use the cluster specified in the
Anchor.toml file.
anchor deployTo deploy to mainnet, simply update the Anchor.toml file to specify the
mainnet cluster.
[provider]
cluster = "Mainnet"
wallet = "~/.config/solana/id.json"Solana programs can be updated by redeploying the program to the same program ID.
To update a program, simply make changes to your program's code and run the
anchor build command to generated an updated .so file.
anchor buildThen run the anchor deploy command to redeploy the updated program.
anchor deployTo reclaim the SOL allocated to a program account, you can close your Solana program.
To close a program, use the solana program close <PROGRAM_ID> command. For
example:
solana program close 3ynNB373Q3VAzKp7m4x238po36hjAGFXFJB4ybN2iTyg --bypass-warningNote that once a program is closed, the program ID cannot be reused to deploy a new program.
Below is an overview of default file structure in an Anchor workspace:
{/* cspell:disable */}
{/* cspell:enable */}
The /programs directory contains your project's Anchor programs. A single
workspace can contain multiple programs.
By default, programs are organized with a modular structure:
lib.rs- Main entry point that declares and exports modulesinstructions/- Directory containing instruction handler functionsstate/- Directory for account structures and state definitionsconstants.rs- Program-wide constantserror.rs- Custom error codes
This modular organization makes it easier to navigate and maintain your code, especially as your program grows in complexity.
The /tests directory contains test files for your project. A default test file
is created for you when you create your project.
The /target directory contains build outputs. The main subfolders include:
/deploy: Contains the keypair and program binary for your programs./idl: Contains the JSON IDL for your programs./types: Contains the TypeScript type for the IDL.
The Anchor.toml file configures workspace settings for your project.
Includes a program-logs file that contains transaction logs from the last run
of test files.
The /app folder is an empty folder that can be optionally used for your
frontend code.