Skip to content

System program

Solana contains a small handful of native programs that are part of the validator implementation and provide various core functionalities for the network.

When developing custom programs on Solana, you will commonly interact with two native programs, the System Program and the BPF Loader.

System program

By default, all new accounts are owned by the System Program. The System Program performs several key tasks such as:

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

On Solana, a wallet is simply an account owned by the System Program. The lamport balance of the wallet is the amount of SOL owned by the account.

Screenshot 2024-09-13 at 5.37.33 PM.png

Using @solana/web3.js to interact with the System program

  • Create a new account with data and rent

    const { Keypair, Connection, SystemProgram, Transaction } = require('@solana/web3.js');
    const payer = Keypair.fromSecretKey(Uint8Array.from([222,61,190,103,38,70,4,221,24,242,44,86,66,111,102,52,87,41,83,45,166,179,184,79,208,91,20,66,142,36,147,236,30,84,33,77,227,36,159,27,27,53,27,249,230,207,30,83,42,51,3,225,70,41,44,85,54,31,198,80,45,49,208,39]));
    const mintAthority = payer;
    const connection = new Connection("https://api.devnet.solana.com");
    async function main() {
    const newAccount = Keypair.generate();
    const TOTAL_BYTES = 165;
    const lamports = await connection.getMinimumBalanceForRentExemption(TOTAL_BYTES);
    const transaction = new Transaction();
    transaction.add(
    SystemProgram.createAccount({
    fromPubkey: payer.publicKey,
    newAccountPubkey: newAccount.publicKey,
    lamports: lamports,
    space: TOTAL_BYTES,
    programId: SystemProgram.programId,
    }),
    );
    await connection.sendTransaction(transaction, [payer, newAccount]);
    console.log(`New account created at ${newAccount.publicKey.toBase58()}`);
    }
    main();

    Screenshot 2024-09-13 at 5.52.14 PM.png

  • Transfer lamports from your account to another account

    const { createMint } = require('@solana/spl-token');
    const { Keypair, Connection, SystemProgram, Transaction } = require('@solana/web3.js');
    const payer = Keypair.fromSecretKey(Uint8Array.from([222,61,190,103,38,70,4,221,24,242,44,86,66,111,102,52,87,41,83,45,166,179,184,79,208,91,20,66,142,36,147,236,30,84,33,77,227,36,159,27,27,53,27,249,230,207,30,83,42,51,3,225,70,41,44,85,54,31,198,80,45,49,208,39]));
    const mintAthority = payer;
    const connection = new Connection("https://api.devnet.solana.com");
    async function main() {
    const newAccount = Keypair.generate();
    const TOTAL_BYTES = 165;
    const lamports = await connection.getMinimumBalanceForRentExemption(TOTAL_BYTES);
    const transaction = new Transaction();
    transaction.add(
    SystemProgram.transfer({
    fromPubkey: payer.publicKey,
    toPubkey: newAccount.publicKey,
    lamports,
    }),
    );
    await connection.sendTransaction(transaction, [payer, newAccount]);
    console.log(`Transferred to ${newAccount.publicKey.toBase58()}`);
    }
    main();

    Screenshot 2024-09-13 at 5.51.06 PM.png

  • Change the owner of an account

    const { createMint } = require('@solana/spl-token');
    const { Keypair, Connection, SystemProgram, Transaction } = require('@solana/web3.js');
    const payer = Keypair.fromSecretKey(Uint8Array.from([222,61,190,103,38,70,4,221,24,242,44,86,66,111,102,52,87,41,83,45,166,179,184,79,208,91,20,66,142,36,147,236,30,84,33,77,227,36,159,27,27,53,27,249,230,207,30,83,42,51,3,225,70,41,44,85,54,31,198,80,45,49,208,39]));
    const connection = new Connection("https://api.devnet.solana.com");
    async function main() {
    const newAccount = Keypair.generate();
    const owner = Keypair.generate();
    const TOTAL_BYTES = 165;
    const lamports = await connection.getMinimumBalanceForRentExemption(TOTAL_BYTES);
    const transaction = new Transaction();
    transaction.add(
    SystemProgram.createAccount({
    fromPubkey: payer.publicKey,
    newAccountPubkey: newAccount.publicKey,
    lamports: lamports,
    space: TOTAL_BYTES,
    programId: owner.publicKey,
    }),
    );
    await connection.sendTransaction(transaction, [payer, newAccount]);
    console.log(`New account created at ${newAccount.publicKey.toBase58()}`);
    }
    main();