Introduction
Upgrading a smart contract allows you to improve or modify your contract without changing its address. This guide will walk you through the process of upgrading a WebAssembly (Wasm) bytecode contract using the Soroban SDK.Prerequisites:
- Basic understanding of the Rust programming language. To brush up on Rust, check out Rustlings or The Rust book.
- Familiarity with Stellar smart contracts
- Installed Stellar CLI and Soroban SDK
Download the upgradeable contract example
The upgradeable contract example demonstrates how to upgrade a Wasm contract.Code
The example contains both an “old” and “new” contract, where we upgrade from “old” to “new”. The code below is for the “old” contract.upgradeable_contract/old_contract/src/lib.rs
How it works
When upgrading a contract, the key function used isenv.deployer().update_current_contract, which takes a ContractExecutable wrapping the Wasm hash of the new contract as a parameter. Here’s a step-by-step breakdown of how this process works:
- No change in contract address: The contract’s address remains the same after the upgrade. This ensures that all references to the contract stay intact.
-
The Wasm executable must already be uploaded: The upgrade depends on the compiled executable (identified by the
new_wasm_hash) being uploaded and available on the blockchain. This must be done prior to invoking the contract’supgrade(...)function. -
Admin authorization: Before upgrading, the contract checks if the action is authorized by the
Adminaddress. This is crucial to prevent unauthorized upgrades. Only someone with admin rights can perform the upgrade. -
The upgrade function: Below is the function that handles the upgrade process:
env: Env: The environment object representing the current state of the blockchain.new_wasm_hash: BytesN<32>: The hash of the new Wasm code for the contract. The Wasm bytecode must already be installed/present on the ledger.- The function first retrieves the admin’s address from the contract’s storage.
- It then requires the admin’s authorization (
admin.require_auth()) to proceed. - Finally, it updates the contract with the new Wasm bytecode (
env.deployer().update_current_contract(ContractExecutable::Wasm(new_wasm_hash))).
-
update_current_contractwill also emit aSYSTEMcontract event that contains the old and newContractExecutable, allowing downstream users to be notified when a contract they use is updated. The event structure will havetopics = ["executable_update", old_executable: ContractExecutable, new_executable: ContractExecutable]anddata = [].
Tests
Open theupgradeable_contract/old_contract/src/test.rs file to follow along.
upgradeable_contract/old_contract/src/test.rs
Build the contract
To build the contract.wasm files, run stellar contract build in both upgradeable_contract/old_contract and upgradeable_contract/new_contract in that order. Both .wasm files should be found in both contract target directories after building both contracts:
Run the contract
If you havestellar-cli installed, you can invoke contract functions. Deploy the old contract and install the Wasm for the new contract.
First, navigate to the upgradeable_contract/old_contract directory, and deploy an instance of the old contract. We’re providing the alice identity to the __constructor function, so it will be the contract’s Admin address. Create and provide your own identities, where necessary.
This command will output the contract address it was deployed to.
upgradeable_contract/new_contract and upload the compiled executable file for the new contract. This command will output the Sha256 hash of the executable, which will be used later for the new_wasm_hash parameter.
old_contract address is CAS6FKBXGVXFGU2SPPPJJOIULJNPMPR6NVKWLOQP24SZJPMB76TGH7Y3. You may need to replace this value with your own. Invoke the version function of the contract, to see the current deployed version.
--source-account should be the identity name matching the address passed to the __constructor function, when the contract was deployed.
version function again. Now that the contract was upgraded, you’ll see a new version.