Hello! Welcome to the next lesson in our "Advanced Anchor and Program Lifecycle" module.
In the last lesson, we tackled a crucial aspect of program evolution: how to upgrade your on-chain data structures. We learned how to implement versioning and use Anchor's realloc constraint to perform "lazy migrations" on accounts, ensuring your program can handle data from different versions without breaking.
Today, we shift our focus from the data to the code. What happens when you need to fix a bug, add a new feature, or change the logic of an instruction? This lesson will teach you how to upgrade the deployed program logic itself using the Solana Command-Line Interface (CLI). This skill is fundamental to maintaining and improving your applications throughout their lifecycle.
The Upgrade Process: Surprisingly Simple
You might expect upgrading a live program on a blockchain to be a complex, multi-step ordeal. However, for Solana, the core process is remarkably straightforward. You use the exact same command for upgrading a program as you do for deploying it for the first time.
The key is that you are deploying the new program code to the same on-chain address, or Program ID. Your program's identity remains constant, but the underlying executable code is replaced.
Let's look at the official documentation to see the command.
The official Solana documentation provides the most direct explanation of the deployment and update process. This section shows that the command for both actions is identical.
Please read the short section titled 'Update Program'. Notice that the command shown is the same as the deploy command we've seen before. Pay attention to the note about what happens if the updated program is larger than the previous version.
As the documentation states, the workflow for an upgrade is:
- Make changes to your program's Rust code.
- Rebuild the program using
anchor build(orcargo build-sbffor native programs). - Deploy the update using
solana program deploy ./target/deploy/<YOUR_PROGRAM_NAME>.so.
The Solana CLI, when pointed at an existing Program ID that your wallet has upgrade authority over, will simply replace the old program executable with the new one.
Handling Program Size Increases
In our last lesson, we saw that we had to use realloc to increase the size of a data account. What happens if our program account needs to grow? For example, adding a new instruction or complex logic will increase the size of the compiled .so file.
The ProgramData account, which stores your program's executable code, is allocated with a specific amount of space on the blockchain. By default, this is double the size of your initial program, giving you room for future upgrades.
But what if your upgrades exceed that initial buffer?
As noted in the documentation you just read, the solana program deploy command is smart. If it detects that the new program binary is larger than the currently allocated space, it will automatically attempt to increase the size of the ProgramData account and charge your wallet for the additional rent required.
However, sometimes you might want or need to manage this process more explicitly. Let's watch a video that touches on this scenario.
Complete Guide to Full Stack Solana Development (2024)
In this segment from Abdullah Raza's 'Complete Guide to Full Stack Solana Development', the instructor encounters an error when trying to deploy a new version of a program that is too large for the existing program account. This provides a practical look at the problem and the solution.
Watch the video from 41:14 to 46:35. Focus on the explanation of why the deployment fails ('account data too small') and the two options presented: creating a new program or extending the old one. Pay close attention to the introduction of the solana program extend command.
The video brings up an important distinction:
- Upgrading Code vs. Changing Data Structures: The instructor correctly points out a major caveat. A simple program code upgrade (what we are focusing on) is straightforward. However, if you fundamentally change an existing account's data layout without a migration strategy (like we learned in the last lesson), a simple code upgrade will fail at runtime. In his specific case, he chose to deploy a completely new program. For our purposes, we assume we've handled data migration correctly and are only concerned with the code and its size.
The key takeaway from the video is the manual alternative to the automatic resizing: the solana program extend command.
If an automatic upgrade fails, or if you want to pre-allocate space as part of a script, you can use:solana program extend <PROGRAM_ID> <ADDITIONAL_BYTES>
This command increases the data size of the program account, funding the additional rent from your wallet. After extending the account, you can then run solana program deploy successfully.
A Practical Upgrade Workflow
Let's formalize the steps for a well-managed program upgrade on devnet.
-
Check Current State: First, get the details of your deployed program. Find your program ID (you can get it from
Anchor.tomlor by runninganchor keys list).solana program show <YOUR_PROGRAM_ID> --url devnetNote the
Data Lengthvalue. This is the total space (in bytes) allocated for your program's executable. -
Make Code Changes & Rebuild: Modify your program logic in
src/lib.rs. For a simple test, you could change the text in amsg!macro. Then, rebuild.anchor build -
Check New Program Size: Compare the old size with the new.
wc -c < ./target/deploy/<YOUR_PROGRAM_NAME>.soIf this new size is greater than the
Data Lengthfrom Step 1, you know the program account will need to be resized. -
Deploy the Upgrade: Run the deploy command, pointing to the devnet cluster. Anchor's
deploycommand is a convenient wrapper that does this for you.# Ensure your Anchor.toml is set to the devnet cluster and your program ID # [provider] # cluster = "devnet" # # [programs.devnet] # my_program = "YOUR_PROGRAM_ID" anchor deployAlternatively, using the Solana CLI directly:
solana program deploy target/deploy/<YOUR_PROGRAM_NAME>.so --url devnet -
Verify the Upgrade: Check the program details again.
solana program show <YOUR_PROGRAM_ID> --url devnetYou should see that the
Last Deployed In Slothas increased, and if the program grew, theData LengthandBalance(due to rent) will have changed. Your upgrade is now live.
Test your understanding!
You've added a significant new feature to your Solana program. After running anchor build, you check the new binary size and find it's 8,000 bytes larger than the Data Length reported by solana program show. When you run anchor deploy, the transaction fails with an error related to insufficient funds, even though you have some SOL. What is the most likely cause, and what is a specific command you could run to fix it before trying to deploy again?
Show answer
The most likely cause is that while the CLI tried to automatically extend the program account, your wallet did not have enough SOL to pay for the additional rent required for 8,000+ bytes of data plus the transaction fees.
To fix this, you could first airdrop yourself more SOL (solana airdrop 2 --url devnet) and then either:
- Try
anchor deployagain, as it might now succeed with the increased balance. - For more direct control, you could manually extend the program account space first:
solana program extend <YOUR_PROGRAM_ID> 8192 --url devnet
(Using a power of 2 like 8192 is common practice). After this succeeds, the subsequentanchor deploycommand will only need to pay for the transaction fee, not the rent for the new space.
Advanced Upgrades: Using a Buffer Account
For high-stakes upgrades, especially on mainnet, deploying directly into the program account can be risky. If the deployment fails midway, you could be left in an inconsistent state. A more robust and secure pattern involves using an intermediate buffer account.
This process separates the uploading of the new code from the actual activation of that code.
Deploy a Solana Program with the CLI
The Solana Labs documentation provides details on more advanced deployment methods. This section introduces the concept of using a buffer account for a safer, multi-step upgrade process.
Read the sections 'Using an intermediary Buffer account' and 'Upgrading program using offline signer as authority'. Don't worry about memorizing the offline signer commands, but understand the workflow: The new code is written to a temporary buffer account. Authority is set on this buffer. A separate command uses the buffer to upgrade the actual program.
The buffer workflow looks like this:
- Write to Buffer: Instead of deploying directly, you upload the new program binary to a new, temporary buffer account.
solana program write-buffer ./target/deploy/program.so - Verify (Optional but Recommended): The authority (e.g., a multi-signature wallet or DAO) can now inspect the bytecode in this buffer account on-chain to verify it matches the intended, audited source code. This is a critical security step.
- Upgrade from Buffer: Once verified, the upgrade authority issues the command to upgrade the program using the data from the buffer.
solana program deploy --buffer <BUFFER_ADDRESS>
This two-step process provides a crucial airlock. It allows for off-chain verification and governance to happen before the new code goes live, which is essential for secure program lifecycle management.
Conclusion
You now understand the mechanics of upgrading Solana program code. While the basic command is simple, the concepts of account size, rent, and advanced buffer-based workflows are essential for professional development.
Key Takeaways:
- Upgrading a program is done with the same
solana program deploycommand used for the initial deployment. - The Program ID remains constant, preserving your program's address.
- The CLI will attempt to automatically resize the program account if the new code is larger, but you can do it manually with
solana program extend. - For secure, mission-critical upgrades, a two-step process using an intermediary buffer account is the recommended best practice.
Preview of the Next Lesson
We've discussed upgrading and mentioned "upgrade authority" several times. But what is this authority? Who holds it, and can it be changed? In our next lesson, we will dive deep into managing the upgrade authority of a deployed program, including how to transfer it and how to make a program permanently immutable.
Can't find a good explanation? Sign up and we'll make it for you
Sign up