Solana smart contracts, known as "programs," are written in Rust and deployed on-chain. If you're a developer looking to build on Solana, this guide will walk you through the essential steps to write and deploy your first program.
Understanding Solana Programs
Unlike Ethereum's smart contracts, Solana uses a different terminology and architecture:
| Ethereum | Solana |
|---|---|
| Smart Contract | Program |
| Contract State | Account |
| Transaction | Instruction |
| Solidity | Rust |
Key differences:
- πΉ Programs are statelessβdata is stored in accounts
- πΉ Multiple accounts can be passed to a single instruction
- πΉ Programs can be upgraded (with proper authority)
Prerequisites
Before starting, you'll need:
- πΉ Basic Rust knowledge
- πΉ Command line familiarity
- πΉ Node.js (for testing and front-end)
- πΉ Some SOL for deployment
Steps to Writing and Deploying Solana Smart Contracts
Step 1: Install the Solana CLI
Download and install the Solana command-line tools:
# Install Solana CLI
sh -c "$(curl -sSfL https://release.solana.com/stable/install)"
# Add to PATH (follow the prompts)
export PATH="$HOME/.local/share/solana/install/active_release/bin:$PATH"
# Verify installation
solana --version
Configure for devnet while learning:
solana config set --url devnet
Step 2: Install Rust and Anchor
Anchor is the most popular framework for Solana development:
# Install Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Install Anchor
cargo install --git https://github.com/coral-xyz/anchor avm --locked
avm install latest
avm use latest
# Verify installation
anchor --version
Step 3: Create Your First Project
Initialize a new Anchor project:
anchor init my_first_program
cd my_first_program
This creates a project structure:
my_first_program/
βββ Anchor.toml
βββ programs/
β βββ my_first_program/
β βββ src/
β βββ lib.rs
βββ tests/
βββ app/
Step 4: Write Your First Smart Contract
Edit programs/my_first_program/src/lib.rs:
use anchor_lang::prelude::*;
declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS");
#[program]
pub mod my_first_program {
use super::*;
pub fn initialize(ctx: Context<Initialize>, data: u64) -> Result<()> {
let my_account = &mut ctx.accounts.my_account;
my_account.data = data;
msg!("Account initialized with data: {}", data);
Ok(())
}
pub fn update(ctx: Context<Update>, new_data: u64) -> Result<()> {
let my_account = &mut ctx.accounts.my_account;
my_account.data = new_data;
msg!("Account updated with new data: {}", new_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>,
}
#[derive(Accounts)]
pub struct Update<'info> {
#[account(mut)]
pub my_account: Account<'info, MyAccount>,
}
#[account]
pub struct MyAccount {
pub data: u64,
}
Step 5: Build Your Program
Compile the program:
anchor build
This generates:
- πΉ Program binary in
target/deploy/ - πΉ IDL (Interface Description Language) for client interaction
- πΉ TypeScript types for your program
Step 6: Deploy Your Program
Get some devnet SOL first:
solana airdrop 2
Deploy to devnet:
anchor deploy
You'll see output like:
Deploying program "my_first_program"...
Program Id: <YOUR_PROGRAM_ID>
Step 7: Interact with Your Contract
Write a test in tests/my_first_program.ts:
import * as anchor from "@coral-xyz/anchor";
import { Program } from "@coral-xyz/anchor";
import { MyFirstProgram } from "../target/types/my_first_program";
describe("my_first_program", () => {
const provider = anchor.AnchorProvider.env();
anchor.setProvider(provider);
const program = anchor.workspace.MyFirstProgram as Program<MyFirstProgram>;
it("Initializes the account", async () => {
const myAccount = anchor.web3.Keypair.generate();
await program.methods
.initialize(new anchor.BN(42))
.accounts({
myAccount: myAccount.publicKey,
user: provider.wallet.publicKey,
systemProgram: anchor.web3.SystemProgram.programId,
})
.signers([myAccount])
.rpc();
const account = await program.account.myAccount.fetch(myAccount.publicKey);
console.log("Account data:", account.data.toString());
});
});
Run the test:
anchor test
Key Concepts to Master
Account Model
- πΉ All state lives in accounts, not in the program
- πΉ Programs are stateless executors
- πΉ Accounts have owners (programs that can modify them)
PDAs (Program Derived Addresses)
- πΉ Deterministic addresses derived from seeds
- πΉ Allow programs to "sign" for accounts
- πΉ Essential for complex program logic
CPIs (Cross-Program Invocations)
- πΉ Programs can call other programs
- πΉ Enable composability in DeFi
- πΉ Require proper account forwarding
Resources for Learning
- πΉ Solana Cookbook - Recipes and examples
- πΉ Anchor Book - Official Anchor documentation
- πΉ Solana Docs - Official documentation
- πΉ Buildspace - Interactive tutorials
Mastering Solana smart contracts opens the door to building powerful decentralized applications. Start with simple programs and gradually tackle more complex logic!