The Upgradability Library provides functions that can be used to implement contract upgrades via simple upgradable proxies. The Upgradability Library implements the required and optional functionality from SRC-14 as well as additional functionality for ownership of the proxy contract.
For implementation details on the Upgradability Library please see the Sway Libs Docs .
In order to use the Upgradability library, Sway Libs and Sway Standards must be added to the Forc.toml
file and then imported into your Sway project. To add Sway Libs as a dependency to the Forc.toml
file in your project please see the Getting Started . To add Sway Standards as a dependency please see the Sway Standards Book .
To import the Upgradability Library and SRC-14 Standard to your Sway Smart Contract, add the following to your Sway file:
use sway_libs::upgradability::*;
use standards::{src14::*, src5::*};
To implement the SRC-14 standard with the Upgradability library, be sure to add the Sway Standards dependency to your contract. The following demonstrates the integration of the Ownership library with the SRC-14 standard.
use sway_libs::upgradability::{_proxy_owner, _proxy_target, _set_proxy_target};
use standards::{src14::{SRC14, SRC14Extension}, src5::State};
storage {
SRC14 {
/// The [ContractId] of the target contract.
///
/// # Additional Information
///
/// `target` is stored at sha256("storage_SRC14_0")
target in 0x7bb458adc1d118713319a5baa00a2d049dd64d2916477d2688d76970c898cd55: Option<ContractId> = None,
/// The [State] of the proxy owner.
///
/// # Additional Information
///
/// `proxy_owner` is stored at sha256("storage_SRC14_1")
proxy_owner in 0xbb79927b15d9259ea316f2ecb2297d6cc8851888a98278c0a2e03e1a091ea754: State = State::Uninitialized,
},
}
impl SRC14 for Contract {
#[storage(read, write)]
fn set_proxy_target(new_target: ContractId) {
_set_proxy_target(new_target);
}
#[storage(read)]
fn proxy_target() -> Option<ContractId> {
_proxy_target()
}
}
impl SRC14Extension for Contract {
#[storage(read)]
fn proxy_owner() -> State {
_proxy_owner()
}
}
NOTE An initialization method must be implemented to initialize the proxy target or proxy owner.
Once imported, the Upgradability Library's functions will be available. Use them to change the proxy target for your contract by calling the set_proxy_target()
function.
#[storage(read, write)]
fn set_proxy_target(new_target: ContractId) {
_set_proxy_target(new_target);
}
Use the proxy_target()
method to get the current proxy target.
#[storage(read)]
fn proxy_target() -> Option<ContractId> {
_proxy_target()
}
To change the proxy target for your contract use the set_proxy_owner()
function.
#[storage(write)]
fn set_proxy_owner(new_proxy_owner: State) {
_set_proxy_owner(new_proxy_owner);
}
Use the proxy_owner()
method to get the current proxy owner.
#[storage(read)]
fn proxy_owner() -> State {
_proxy_owner()
}
To restrict a function to only be callable by the proxy's owner, call the only_proxy_owner()
function.
#[storage(read)]
fn only_proxy_owner_may_call() {
only_proxy_owner();
// Only the proxy's owner may reach this line.
}