Upgradeable Contract
#![no_std]
use soroban_sdk::{contract, contractimpl, contracterror, contracttype, Address, BytesN, Env, log};
#[derive(Clone)]
#[contracttype]
enum DataKey {
Admin,
}
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
#[contracterror]
#[repr(u32)]
pub enum Error {
AlreadyInitialized = 1,
}
#[contract]
pub struct UpgradeableContract;
#[contractimpl]
impl UpgradeableContract {
pub fn init(env: Env, admin: Address) -> Result<(), Error> {
if env.storage().instance().has(&DataKey::Admin) {
return Err(Error::AlreadyInitialized);
}
env.storage().instance().set(&DataKey::Admin, &admin);
/// @dev should remove logs before deploying smart contracts
log!(&env, "Admin address: {}", admin);
Ok(())
}
pub fn version() -> u32 {
1
}
pub fn upgrade(env: Env, new_wasm_hash: BytesN<32>) {
let admin: Address = env.storage().instance().get(&DataKey::Admin).unwrap();
admin.require_auth();
env.deployer().update_current_contract_wasm(new_wasm_hash);
}
}
Explanation
#![no_std]
This attribute prevents linking to the standard library, making the code lighter and more efficient for Soroban contracts. It's big so we save on size.
use soroban_sdk::{contract, contractimpl, Env, log}
Imports stuffs from the Soroban SDK. Env
is basic Soroban type, we need it because we can't use the Rust standard library.
DataKey
This is an enumerated type (enum
) used to define different keys for storing data in the contract's storage. Currently, the only option is Admin
.
Error
This is another enumerated type defining a specific error code: AlreadyInitialized
.
init
This function checks if the Admin
key already exists in storage. If it does, it returns the AlreadyInitialized
error. Otherwise, it sets the Admin
key with the provided admin
address and returns success (Ok(())
).
upgrade
This retrieves the current administrator address from storage using the Admin key. It then uses require_auth
(likely from the Soroban SDK) to ensure only the administrator can call this function. Finally, it utilizes the deployer
functionality from the environment to update the contract's bytecode with the provided new_wasm_hash
.
Run in Playground
Loading playground...