Skip to content

Programs

Programs

In Solana, a Program is the equivalent of a smart contract on other blockchains. Programs are executable code stored on the blockchain, composed of eBPF bytecode, and invoked through instructions in transactions to execute specific logic.

Program Characteristics

Stateless Solana programs do not store state themselves: - Program code is read-only - All state is stored in separate accounts - Programs access data through account parameters

This design enables programs to execute in parallel, improving performance.

Upgradable vs Non-Upgradable - Non-upgradable programs: Code cannot be changed after deployment — secure but inflexible - Upgradable programs: Code can be updated through upgrade authority — flexible but requires trust

Rent-exempt Program accounts must meet the rent-exempt threshold to ensure permanent existence.

Program Types

1. Native Programs Built-in system programs in Solana: - System Program: Creates accounts, transfers SOL - Token Program: SPL Token operations - Associated Token Program: Token account management - BPF Loader: Loads and upgrades programs

2. Custom Programs Programs written by developers: - Written in Rust, C - Compiled to eBPF bytecode - Deployed on-chain

Program Development

Basic Structure

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

entrypoint!(process_instruction);

pub fn process_instruction(
    program_id: &Pubkey,
    accounts: &[AccountInfo],
    instruction_data: &[u8],
) -> ProgramResult {
    // Business logic
    Ok(())
}

Using the Anchor Framework

use anchor_lang::prelude::*;

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

    pub fn initialize(ctx: Context<Initialize>, data: u64) -> Result<()> {
        let account = &mut ctx.accounts.my_account;
        account.data = data;
        Ok(())
    }
}

#[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>,
}

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

Program Deployment

1. Build

cargo build-bpf

2. Deploy

solana program deploy target/deploy/my_program.so

3. Upgrade

solana program upgrade target/deploy/my_program.so <PROGRAM_ID>

Program Account Structure

Each program has two associated accounts:

Program Account - Stores eBPF bytecode - Marked as executable - Owned by BPF Loader

Program Data Account - Stores the actual program code data - Exclusive to upgradable programs - Contains upgrade authority information

Cross-Program Invocation (CPI)

Programs can call other programs:

invoke(
    &instruction,
    &[account1, account2],
)?;

// Or using PDA signing
invoke_signed(
    &instruction,
    &[account1, account2, pda],
    &[&[b"seed", &[bump]]],
)?;

CPI Limits - Maximum call depth: 4 levels - Inherits caller's permissions - Shares CU budget

Program Security

Common Vulnerabilities - Missing signer checks - Insufficient account owner verification - Integer overflow - Reentrancy attacks - Missing PDA derivation verification

Security Best Practices - Use Anchor framework constraint checks - Validate all input parameters - Use safe math operations - Conduct audits and testing

Program Optimization

1. Reduce CU Consumption - Optimize algorithms - Reduce account access - Use zero-copy

2. Reduce Program Size - Remove unused dependencies - Use LTO (Link Time Optimization) - Compress instructions

3. Improve Parallelism - Clearly specify account read/write permissions - Avoid unnecessary writable accounts

  • eBPF: The bytecode format for programs
  • Anchor: A popular Solana program development framework
  • CPI: Cross-Program Invocation mechanism
  • PDA: Program Derived Address, accounts controlled by programs