Overview
This guide walks through the process of deploying a smart contract from installed Wasm bytecode using a deployer contract. We will cover setting up your environment, uploading Wasm bytecode, and deploying and initializing a contract atomically.Prerequisites:
- Basic understanding of Rust programming language. To brush up on Rust, check out Rustlings or The Rust book.
- Familiarity with Stellar smart contracts
- Installed Cargo, Stellar CLI and Soroban SDK
Setup environment
The deployer example demonstrates how to deploy contracts using a contract.- Clone the Soroban Examples Repository:
- Navigate to the Deployer Example:
For this example to work, you should navigate to
deployer/contract and deployer/deployer and run the command stellar contract build in each directory to generate the target files.- Run tests:
deployer/deployer, run the following command:
Code overview
deployer/deployer/src/lib.rs
How it works
The deployer contract provides a mechanism to deploy other contracts in a secure and deterministic manner. It stores an administrator address at construction time and requires that administrator’s authorization for every deployment. It also supports atomic initialization of the newly deployed contract via constructor arguments. This guarantees that the contract is properly initialized immediately after deployment, preventing any potential issues with uninitialized contracts.Function breakdown
env: Env: The Env object represents the current contract execution environment. It provides methods to interact with the blockchain and other contracts, as well as perform various operations.admin: Address: The Address of the administrator, provided to the__constructorfunction and stored for later use. Only this address can authorize deployments.wasm_hash: BytesN<32>: The hash of the Wasm bytecode of the contract to be deployed and must already be installed and on the ledger. This hash is used to uniquely identify the contract’s code.salt: BytesN<32>: A unique value used to derive the address of the deployed contract. The same combination of theDeployercontract’s address and salt will always produce the same deployed contract address, ensuring deterministic contract addresses.constructor_args: Vec<Val>: A vector of arguments, specified as{type: value}objects, to be passed to the constructor of the deployed contract.
Function steps
- Uses the
env.deployer()method to create a deployer object. with_address(env.current_contract_address(), salt)specifies that the deployed contract’s address is derived from theDeployercontract’s own address and the given salt.deploy_contract(ContractExecutable::Wasm(wasm_hash), constructor_args)deploys the contract using the provided Wasm bytecode hash, invokes its constructor withconstructor_args, and returns the address of the newly deployed contract.
Build the contracts
To build the contract into a.wasm file, use the stellar contract build command. This command builds both the deployer contract and the test contract.
.wasm files should be found in both contract target directories after building both contracts:
Run the contract
Before deploying the test contract with the deployer, install the test contract Wasm using theupload command. The upload command will print out the hash derived from the Wasm file which should be used by the deployer.
alice identity to your own.
The command prints out the hash as hex. It will look something like 6bc6d975ef99c057231481c40f69f4c2a8a89ac56e8826ef0378f8e5c6abc4be.
We also need to deploy the Deployer contract. Since the Deployer contract’s __constructor function requires an administrator address, we provide the alice identity as the --admin argument. Create and provide your own identity, where necessary.
CDKYZMA3OXR54YAHOQ5D4EWDFDT3ZNKKRYKQT7MGPWH22ZVD2DX2BJID.
Then the deployer contract may be invoked with the Wasm hash value above. The constructor_args are passed through to the constructor of the deployed contract, so they are used here to set the initial value to 8.
CCTVFX6BFTQHTGAHA5TY4YZQJRUKRE2RRNUTGVBNKE3PJF5C7CI53APY) of the newly deployed test contract.
Invoke the deployed test contract using the address returned from the previous command.