Back to Videos

System Program Library: How to use it & why?

Wednesday, May 21, 2025

Neon Dev Bootcamp – Week 3: System Program Library: how to use it & why?

Lesson Overview

Welcome to Week 3 of the Neon Dev Bootcamp!

In this module, you’ll gain hands-on experience using one of the core components of Neon EVM composability: the System Program Library. This powerful Solidity library abstracts the Solana-native system program instructions, allowing EVM developers to:

  • Create Solana accounts from Solidity
  • Transfer SOL between accounts
  • Assign account ownership
  • Allocate account storage
  • Query Solana account metadata (owner, balance, executable flag, etc.)

By the end of this lesson, you’ll be able to fully manage Solana accounts from Solidity without learning Rust or diving into Solana's low-level instruction mechanics.

Repo Setup

We’ll be working directly with the following GitHub repository:

🔗 Neon Solidity Composability Libraries

Clone it:

git clone https://github.com/neonevm/neon-contracts.git
cd neon-contracts/solidity-composability-libraries
npm install

Background: Ethereum vs Solana Accounts

Ethereum Accounts

Concept Value
Types EOA, Contract
Data Stored internally via state variables
Creation Implicit with keypair
Ownership Private-key controlled
Storage Dynamically allocated
Native token (ETH) Transferred with a single call

Solana Accounts

Concept Value
Types Program, Data, Sysvar
Data External, must be allocated
Creation Explicit + Rent-exempt
Ownership Assigned to programs
Storage Predefined byte size
Native token (SOL) Sent via formatted instructions

Solana treats everything as an account, and every account must be explicitly created, sized, and owned by a program.

By default, all new accounts are owned to the System Program. The System Program does a few key things:

  • New Account Creation: Only the System Program can create new accounts.
  • Space Allocation: Sets the byte capacity for the data field of each account.
  • Transfer / Assign Program Ownership: Once the System Program creates an account, it can reassign the designated program owner to a different program account. That's how custom programs take ownership of new accounts created by the System Program.

Introducing the System Program Library

The LibSystemProgram and LibSystemData are the main files in the Neon EVM’s custom System Program library that abstracts Solana’s System Program and provides familiar EVM-style interactions.

Module Purpose
LibSystemProgram Instruction builder (create, assign, transfer, allocate)
LibSystemData State reader with a list of getters (balance, ownership, space, etc.)

These libraries enable you to issue Solana-native instructions directly from Solidity smart contracts.

Step-by-Step: System Program in Practice

Instruction 1: Create Account with Seed


bytes memory instr = LibSystemProgram.formatCreateAccountWithSeedInstruction(
   payer,
   base,
   programId,
   seed,
   space
);

Parameters:

  • payer: Address funding account creation
  • base: Usually the smart contract address
  • programId: Solana program to own the account
  • seed: Custom 32-byte seed (used to derive the PDA)
  • space: Storage size (e.g., 165 bytes for SPL token accounts)

Note: Only the "create with seed" method is supported by Neon EVM’s library because it’s deterministic and doesn’t expose private keys.

The library will:

  • Calculate rent exemption automatically
  • Return the complete Solana instruction data
  • Assemble account list with correct signer/writable roles

Instruction 2: Transfer SOL


bytes memory instr = LibSystemProgram.formatTransferInstruction(
   sender,
   recipient,
   amount
);

Allows transferring SOL between accounts using Solana’s native instruction format.

Instruction 3: Assign Ownership


bytes memory instr = LibSystemProgram.formatAssignWithSeedInstruction(
   account,
   base,
   seed,
   newProgramId
);

Reassigns ownership of a derived Solana account to a new program.

Instruction 4: Allocate Space


bytes memory instr = LibSystemProgram.formatAllocateWithSeedInstruction(
   account,
   base,
   seed,
   space
);

Allocates storage space to a program-derived account. Required before writing any data.

Reading Account Data

LibSystemData gives you getter functions to inspect Solana accounts:


uint64 balance = LibSystemData.getBalance(account);
address owner = LibSystemData.getOwner(account);
bool isExecutable = LibSystemData.getIsExecutable(account);
uint64 rentEpoch = LibSystemData.getRentEpoch(account);
uint64 space = LibSystemData.getSpace(account);

  • getIsExecutable: Returns true if account holds program bytecode
  • getRentEpoch: Epoch when rent needs to be paid or when rent-exemption expires
  • getSpace: Returns how many bytes the account has allocated

Example: CallSystemProgram Contract

Contract: CallSystemProgram.sol

This demo contract walks through:

  • Creating an account with a seed
  • Transferring SOL
  • Assigning program ownership
  • Allocating storage
  • Reading account properties via LibSystemData

Test Script

Run the test suite:

npx hardhat test test/composability/system.test.js --network neondevnet

Covered Tests:

  • Account creation using seed
  • SOL transfer instruction
  • Ownership assignment
  • Storage allocation
  • Getter validations for account data

Resources

Practice exercise

Main task: Create an account on Solana and transfer SOLs using this library

Bonus points: Try extending the contract with your own custom instruction

Back to Videos