Icon HelpCircleForumIcon Link

⌘K

Icon HelpCircleForumIcon Link
Upgradability

Icon LinkUpgradability Library

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 Icon Link as well as additional functionality for ownership of the proxy contract.

For implementation details on the Upgradability Library please see the Sway Libs Docs Icon Link.

Icon LinkImporting the Upgradability Library

In order to use the Upgradability library, Sway Libs and Sway Standards Icon Link 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 Icon Link.

To import the Upgradability Library and SRC-14 Icon Link Standard to your Sway Smart Contract, add the following to your Sway file:

use sway_libs::upgradability::*;
use standards::{src14::*, src5::*};

Icon LinkIntegrating the Upgradability Library into the SRC-14 Standard

To implement the SRC-14 Icon Link 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};
 
#[namespace(SRC14)]
storage {
    // target is at sha256("storage_SRC14_0")
    target: Option<ContractId> = None,
    proxy_owner: 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(storage.proxy_owner)
    }
}
Icon InfoCircle

NOTE An initialization method must be implemented to initialize the proxy target or proxy owner.

Icon LinkBasic Functionality

Icon LinkSetting and getting a Proxy Target

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()
}

Icon LinkSetting and getting a Proxy Owner

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, storage.proxy_owner);
}

Use the proxy_owner() method to get the current proxy owner.

#[storage(read)]
fn proxy_owner() -> State {
    _proxy_owner(storage.proxy_owner)
}

Icon LinkProxy access control

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(storage.proxy_owner);
    // Only the proxy's owner may reach this line.
}