Skip to main content

Your First Solana Program

In this lab, we'll create the simplest possible Solana program - a "Hello World" program that does nothing but can be deployed to the blockchain. This is similar to the empty contract in MultiversX, serving as a foundation for more complex programs.

Prerequisites

Before starting, make sure you have completed the Solana Prerequisites guide:

  • ✅ Solana CLI installed
  • ✅ Anchor framework installed
  • ✅ Rust toolchain installed
  • ✅ Development keypair created
  • ✅ Test SOL on devnet

Creating a New Anchor Project

Anchor provides a convenient way to scaffold a new Solana program project.

Initialize Project

Create a new Anchor project:

anchor init hello-world
cd hello-world

This command creates a new directory with the following structure:

hello-world/
├── Anchor.toml # Anchor configuration file
├── Cargo.toml # Rust workspace configuration
├── package.json # Node.js dependencies
├── programs/
│ └── hello-world/
│ ├── Cargo.toml # Program dependencies
│ └── src/
│ └── lib.rs # Main program file
├── tests/
│ └── hello-world.ts # TypeScript test file
└── migrations/
└── deploy.ts # Deployment script

Understanding the Project Structure

  • programs/hello-world/src/lib.rs: The main Solana program code (Rust)
  • tests/hello-world.ts: Tests for the program (TypeScript)
  • Anchor.toml: Configuration file specifying program IDs, clusters, etc.
  • migrations/deploy.ts: Script to deploy the program

The Default Program

Let's examine the default program that Anchor generates. Open programs/hello-world/src/lib.rs:

use anchor_lang::prelude::*;

declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS");

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

pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
msg!("Hello, World!");
Ok(())
}
}

#[derive(Accounts)]
pub struct Initialize {}

Understanding the Code

Let's break down each part:

  1. use anchor_lang::prelude::*;

    • Imports Anchor's prelude, which includes commonly used types and macros
  2. declare_id!(...)

    • Declares the program ID (public key) for this program
    • Anchor generates this automatically
    • This ID uniquely identifies your program on the blockchain
  3. #[program]

    • Marks the module as the main program module
    • All public functions in this module become callable program instructions
  4. pub fn initialize(ctx: Context<Initialize>) -> Result<()>

    • A public function that can be called from outside the program
    • Context<Initialize> provides access to accounts and program info
    • Returns Result<()> - success or error
  5. msg!("Hello, World!");

    • Logs a message that appears in program logs
    • Useful for debugging
  6. #[derive(Accounts)]

    • Defines the account structure for the instruction
    • Initialize {} is empty, meaning no accounts are required

Building the Program

Before deploying, we need to build the program:

anchor build

This command:

  • Compiles the Rust program to BPF bytecode
  • Generates the Program Derived Address (PDA)
  • Creates the program binary
  • Generates the IDL (Interface Definition Language) file

Expected Output:

Building...
Compiling hello-world v0.1.0
Finished release [optimized] target(s) in X.XXs

The compiled program will be in target/deploy/hello_world.so.

Deploying to Devnet

Option 1: Using Anchor Deploy

The simplest way to deploy:

anchor deploy

This will:

  1. Build the program (if not already built)
  2. Deploy to the cluster specified in Anchor.toml
  3. Display the program ID

Option 2: Manual Deployment

You can also deploy manually:

# Build first
anchor build

# Deploy using Solana CLI
solana program deploy target/deploy/hello_world.so

Verify Deployment

Check that your program is deployed:

solana program show <your-program-id>

Or view it in the explorer:

Testing the Program

Anchor generates a test file for you. Let's examine tests/hello-world.ts:

import * as anchor from "@coral-xyz/anchor";
import { Program } from "@coral-xyz/anchor";
import { HelloWorld } from "../target/types/hello_world";
import { assert } from "chai";

describe("hello-world", () => {
// Configure the client to use the local cluster.
anchor.setProvider(anchor.AnchorProvider.env());

const program = anchor.workspace.HelloWorld as Program<HelloWorld>;

it("Initializes", async () => {
const tx = await program.methods.initialize().rpc();
console.log("Your transaction signature", tx);
});
});

Run Tests

Make sure you have a local validator running or are connected to devnet:

# If using local validator, start it first:
solana-test-validator

# In another terminal, run tests:
anchor test

Expected Output:

  hello-world
✓ Initializes (XXXms)

1 passing (XXs)

Simplifying to a True "Hello World"

The default program includes an initialize function. For a true minimal program (like the empty contract), we can simplify it further:

use anchor_lang::prelude::*;

declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS");

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

// This is the minimal program - it does nothing
// but can still be deployed to the blockchain
}

However, Solana programs require at least one instruction, so we'll keep a minimal one:

use anchor_lang::prelude::*;

declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS");

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

pub fn say_hello(_ctx: Context<SayHello>) -> Result<()> {
msg!("Hello, World from Solana!");
Ok(())
}
}

#[derive(Accounts)]
pub struct SayHello {}

Understanding Program Size

After building, check the program size:

ls -lh target/deploy/hello_world.so

Solana programs have a size limit:

  • Maximum Program Size: 10 KB (10,240 bytes) for on-chain programs
  • Upgradeable Programs: Can be larger but must fit in the upgrade buffer

Our minimal program should be well under this limit.

Program ID and Upgradability

Program ID

The program ID is defined in:

  • declare_id!() macro in lib.rs
  • Anchor.toml under [programs.devnet]

These must match for the program to work correctly.

Making Programs Upgradeable

By default, Anchor programs are upgradeable. This means:

  • You can update the program code
  • The program address stays the same
  • You need the upgrade authority keypair

To deploy as non-upgradeable (final):

solana program deploy --program-id <keypair-file> target/deploy/hello_world.so --final

Practice Exercises

Exercise 1: Create and Deploy

  1. Create a new Anchor project called my-first-program
  2. Build the program
  3. Deploy it to devnet
  4. Verify the deployment in Solana Explorer

Exercise 2: Modify the Program

  1. Add a new instruction called greet that takes a name parameter
  2. Log a personalized greeting
  3. Rebuild and redeploy
  4. Test the new instruction

Exercise 3: Compare with MultiversX

  1. Compare the Solana program structure with the MultiversX empty contract
  2. Note the differences in:
    • Language and framework
    • Deployment process
    • Program size
    • Upgrade mechanism

Common Issues and Solutions

Issue: Build Fails

Error: error: linker 'cc' not found

  • Solution: Install a C compiler (build-essential on Linux, Xcode on macOS)

Issue: Deployment Fails

Error: Error: Account not found

  • Solution: Make sure you have SOL in your account: solana airdrop 2

Issue: Program ID Mismatch

Error: Error: Invalid program id

  • Solution: Make sure the program ID in lib.rs matches Anchor.toml

Issue: Tests Fail

Error: Error: Connection refused

  • Solution: Start local validator: solana-test-validator

Next Steps

Now that you've created your first Solana program:

  1. ✅ Understand the basic program structure
  2. ✅ Know how to build and deploy
  3. ✅ Understand how to test programs
  4. ➡️ Proceed to Solana Program with State (when available)
  5. ➡️ Learn about Solana Accounts (when available)

Summary

In this lab, you've learned:

  • How to create a new Anchor project
  • The structure of a Solana program
  • How to build and deploy Solana programs
  • How to test Solana programs
  • The difference between upgradeable and non-upgradeable programs

This minimal program serves as the foundation for all Solana program development.