---
title: Program Deployment
description: Deploying, upgrading, and verifying Solana programs.
url: /docs/core/programs/program-deployment
type: reference
prerequisites:
  - /docs/core/programs
  - /docs/core/programs/program-execution
related:
  - /docs/core/accounts/account-types
  - /docs/core/programs/builtin-programs
  - /docs/core/transactions
---

<Callout type="info" title="Summary">
  Programs deployed via loader-v3 can be upgraded when an upgrade authority is
  set. Revoking the authority makes the program immutable. Covers the upgrade
  mechanism, loader-v3 deployment and upgrade instructions, build verification,
  and the available loader programs.
</Callout>

## Deploying programs

<Cards>
  <Card title="Native Rust" href="/docs/programs/deploying">
    Deploy using the Solana CLI with `solana program deploy`.
  </Card>
  <Card title="Anchor" href="https://www.anchor-lang.com/docs/quickstart/local">
    Deploy using the Anchor framework with `anchor deploy`.
  </Card>
</Cards>

## Upgrading programs

To upgrade a program, an account must hold the upgrade authority (typically the
account that originally [deployed the program](/docs/programs/deploying)).
During deployment or upgrade, new bytecode is uploaded to a temporary buffer
account, then written to the program data account. Setting the upgrade authority
to _rs`None`_ makes the program immutable and permanently prevents further
updates.

### Upgrade mechanism

When
[`UpgradeableLoaderInstruction::Upgrade`](https://github.com/anza-xyz/agave/blob/v3.1.8/programs/bpf_loader/src/lib.rs#L662)
is processed, the runtime:

1. Verifies the Program account is writable and owned by loader-v3.
2. Verifies the Buffer account contains a _rs`Buffer`_ state with the correct
   authority.
3. Verifies the ProgramData account's `upgrade_authority_address` matches and is
   not _rs`None`_.
4. Verifies the program was not already deployed in the current slot
   (`clock.slot != slot`).
5. Loads and verifies the new ELF bytes from the buffer.
6. Copies the new bytecode from the buffer into the ProgramData account and
   zeros remaining bytes.
7. Funds the ProgramData account to rent-exemption.
8. Drains the buffer account (sets lamports to 0) and truncates its data.
9. The new version becomes effective in the next slot (`deployment_slot + 1`).

The `Program` account itself (its state and the `programdata_address` pointer)
does not change during an upgrade. Only the _rs`ProgramData`_ account's bytecode
and slot metadata are updated.

## Loader-v3 instruction reference

Loader-v3 (BPF Loader Upgradeable) is the current default loader for deploying
programs on Solana.

| Instruction                                                                                                  | Description                                                                                                                                                                                                                                  |
| ------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [`InitializeBuffer`](https://github.com/anza-xyz/agave/blob/v3.1.8/programs/bpf_loader/src/lib.rs#L454)      | Sets a buffer account's state to `Buffer` with the specified authority. Fails if already initialized.                                                                                                                                        |
| [`Write`](https://github.com/anza-xyz/agave/blob/v3.1.8/programs/bpf_loader/src/lib.rs#L469)                 | Writes bytes at the specified offset in a buffer account. Authority must sign.                                                                                                                                                               |
| [`DeployWithMaxDataLen`](https://github.com/anza-xyz/agave/blob/v3.1.8/programs/bpf_loader/src/lib.rs#L498)  | Creates a new program: derives the ProgramData address, creates the ProgramData account via CPI to System Program, verifies and deploys the ELF from the buffer, sets the Program account's state and marks it executable.                   |
| [`Upgrade`](https://github.com/anza-xyz/agave/blob/v3.1.8/programs/bpf_loader/src/lib.rs#L662)               | Replaces the bytecode in an existing program's ProgramData account from a buffer.                                                                                                                                                            |
| [`SetAuthority`](https://github.com/anza-xyz/agave/blob/v3.1.8/programs/bpf_loader/src/lib.rs#L835)          | Changes the authority of a Buffer or ProgramData account. Setting to `None` on ProgramData makes the program immutable. Buffer authority cannot be set to `None`.                                                                            |
| [`SetAuthorityChecked`](https://github.com/anza-xyz/agave/blob/v3.1.8/programs/bpf_loader/src/lib.rs#L892)   | Like `SetAuthority`, but requires the new authority to also sign the transaction.                                                                                                                                                            |
| [`Close`](https://github.com/anza-xyz/agave/blob/v3.1.8/programs/bpf_loader/src/lib.rs#L960)                 | Closes a buffer, uninitialized, or ProgramData account by transferring its lamports to a recipient. Closing ProgramData also writes a `Closed` tombstone to the program cache. Cannot close a program that was deployed in the current slot. |
| [`ExtendProgramChecked`](https://github.com/anza-xyz/agave/blob/v3.1.8/programs/bpf_loader/src/lib.rs#L1071) | Extends the ProgramData account's allocation by additional bytes, funding the extra rent from the payer.                                                                                                                                     |

## Verifying programs

Solana supports [verifiable builds](/docs/programs/verified-builds), which let
users confirm that a program's onchain bytecode matches its public source code.
The Anchor framework provides
[built-in support](https://www.anchor-lang.com/docs/verifiable-builds) for
verifiable builds.

To check verification status for a deployed program, search for its program ID
on the
[Solana Explorer](https://explorer.solana.com/address/PhoeNiXZ8ByJGLkxNfZRnkUfjvmuYqLR89jjFHGqdXY),
or use the Ellipsis Labs
[Solana Verifiable Build CLI](https://github.com/Ellipsis-Labs/solana-verifiable-build)
to independently verify onchain programs.

## Loader programs

| Loader                     | Address                                       | Upgradeable                         | Description                                           |
| -------------------------- | --------------------------------------------- | ----------------------------------- | ----------------------------------------------------- |
| **Native Loader**          | `NativeLoader1111111111111111111111111111111` | Only via validator software upgrade | Owns builtins (System, Vote, Stake) and other loaders |
| **BPF Loader (v1)**        | `BPFLoader1111111111111111111111111111111111` | No (loader management disabled)     | Legacy programs                                       |
| **BPF Loader (v2)**        | `BPFLoader2111111111111111111111111111111111` | No (loader management disabled)     | Legacy programs                                       |
| **BPF Loader Upgradeable** | `BPFLoaderUpgradeab1e11111111111111111111111` | Yes, if upgrade authority is set    | Owns all newly deployed programs                      |
