Any developer can write and deploy programs to the Solana blockchain. Programs (known as smart contracts on other protocols) serve as the foundation for on-chain activity, powering anything from DeFi and NFTs to Social Media and Gaming.
- Programs process instructions from both end users and other programs
- All programs are stateless: any data they interact with is stored in separate accounts that are passed in via instructions
- Programs themselves are stored in accounts marked as
- All programs are owned by the BPF Loader and executed by the Solana Runtime
- Developers most commonly write programs in Rust or C++, but can choose any language that targets the LLVM's BPF backend
- All programs have a single entry point where instruction processing takes place (i.e.
process_instruction); parameters always include:
Unlike most other blockchains, Solana completely separates code from data. All data that programs interact with are stored in separate accounts and passed in as references via instructions. This model allows for a single generic program to operate across various accounts without requiring additional deployments. Common examples of this pattern are seen across the Native and SPL Programs.
Native Programs & The Solana Program Library (SPL)
Solana comes equipped with a number of programs that serve as core building blocks for on-chain interactions. These programs are divided into Native Programs and Solana Program Library (SPL) Programs.
Native Programs provide the base functionality that is required to operate validators. Among these programs, the most well known is the System Program which is responsible for administering new accounts and transferring SOL between two parties.
SPL Programs support a number of on-chain activities, including creating, swapping, and lending tokens, as well as generating stake pools and maintaining an on-chain name service. The SPL Token Program can be invoked directly via the CLI, while others like the Associated Token Account Program are usually composed with custom programs.
Programs are most commonly developed with Rust or C++, but can be developed with any language that targets the LLVM’s BPF backend. Recent initiatives by Neon Labs and Solang enable EVM compatibility and allow developers to write programs in Solidity.
Most Rust-based programs adhere to the following architecture:
|entrypoint.rs||Entrypoint to the program|
|instruction.rs||Program API, (de)serializing instruction data|
|state.rs||Program objects, (de)serializing state|
Recently, Anchor has emerged as a popular framework for developing programs. Anchor is an opinionated framework, akin to Ruby on Rails, that reduces boilerplate and streamlines the (de)serialization process for Rust-based development.
Programs are usually developed and tested against Localhost and Devnet environments before being deployed to Testnet or Mainnet. Solana supports the following environments:
|Cluster Environment||RPC Connection URL|
|Localhost||Default port: 8899 (e.g. http://localhost:8899, http://192.168.1.88:8899)|
Once deployed to an environment, clients can interact with on-chain programs via RPC connections to the respective cluster.
Developers can deploy their programs via the CLI:
solana program deploy <PROGRAM_FILEPATH>
When a program is deployed, it is compiled to an ELF shared object (containing BPF bytecode) and uploaded to the Solana cluster. Programs live in accounts (much like everything else on Solana), except these accounts are marked as
executable and assigned to the BPF Loader. The address of this account is referred to as the
program_id and is used to reference the program in all future transactions.
Solana supports multiple BPF Loaders, with the latest being the Upgradable BPF Loader. The BPF Loader is responsible for administering the program’s account and making it available to clients via the
program_id. All programs have a single entry point where instruction processing takes place (i.e.
process_instruction) and parameters always include:
Once invoked, programs are executed by the Solana Runtime.