System Program Library: How to use it & why?
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
Solana Accounts
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.
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 creationbase
: Usually the smart contract addressprogramId
: Solana program to own the accountseed
: 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
: Returnstrue
if account holds program bytecodegetRentEpoch
: Epoch when rent needs to be paid or when rent-exemption expiresgetSpace
: 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