> ## Documentation Index
> Fetch the complete documentation index at: https://developers.stellar.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Deploy a contract from installed Wasm bytecode using a deployer contract

> Deploy a contract from installed Wasm bytecode using a deployer contract

## 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](https://www.rust-lang.org). To brush up on Rust, check out [Rustlings](https://github.com/rust-lang/rustlings) or [The Rust book](https://doc.rust-lang.org/book).
* Familiarity with [Stellar smart contracts](https://developers.stellar.org/docs/build/smart-contracts/getting-started/hello-world.md)
* Installed Cargo, [Stellar CLI](https://developers.stellar.org/docs/build/smart-contracts/getting-started/setup.md#install-the-stellar-cli) and Soroban SDK

### Setup environment

The [deployer example](https://github.com/stellar/soroban-examples/tree/main/deployer) demonstrates how to deploy contracts using a contract.

1. Clone the Soroban Examples Repository:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
git clone -b main https://github.com/stellar/soroban-examples
```

2. Navigate to the Deployer Example:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
cd soroban-examples/deployer/deployer
```

> [!NOTE]
>
> 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.

3. Run tests:

In the `deployer/deployer`, run the following command:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
cargo test
```

You should see the output indicating the tests passed:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
running 1 test
test test::test ... ok
```

### Code overview

```rust title="deployer/deployer/src/lib.rs" theme={"theme":{"light":"github-light","dark":"github-dark"}}
#[contract]
pub struct Deployer;

const ADMIN: Symbol = symbol_short!("admin");

#[contractimpl]
impl Deployer {
    /// Construct the deployer with a provided administrator.
    pub fn __constructor(env: Env, admin: Address) {
        env.storage().instance().set(&ADMIN, &admin);
    }

    /// Deploys the contract on behalf of the `Deployer` contract.
    ///
    /// This has to be authorized by the `Deployer`s administrator.
    pub fn deploy(
        env: Env,
        wasm_hash: BytesN<32>,
        salt: BytesN<32>,
        constructor_args: Vec<Val>,
    ) -> Address {
        let admin: Address = env.storage().instance().get(&ADMIN).unwrap();
        admin.require_auth();

        // Deploy the contract using the uploaded Wasm with given hash on behalf
        // of the current contract.
        // Note, that not deploying on behalf of the admin provides more
        // consistent address space for the deployer contracts - the admin could
        // change or it could be a completely separate contract with complex
        // authorization rules, but all the contracts will still be deployed
        // by the same `Deployer` contract address.
        let deployed_address = env
            .deployer()
            .with_address(env.current_contract_address(), salt)
            .deploy_contract(ContractExecutable::Wasm(wasm_hash), constructor_args);

        deployed_address
    }
}
```

## 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 `__constructor` function 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 the `Deployer` contract'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

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
let admin: Address = env.storage().instance().get(&ADMIN).unwrap();
admin.require_auth();
```

The function loads the administrator address that was stored during construction and requires its authorization, ensuring that only the administrator can trigger a deployment.

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
let deployed_address = env
   .deployer()
   .with_address(env.current_contract_address(), salt)
   .deploy_contract(ContractExecutable::Wasm(wasm_hash), constructor_args);
```

* 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 the `Deployer` contract'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 with `constructor_args`, and returns the address of the newly deployed contract.

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
deployed_address
```

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.

```sh theme={"theme":{"light":"github-light","dark":"github-dark"}}
stellar contract build
```

Both `.wasm` files should be found in both contract `target` directories after building both contracts:

```
target/wasm32v1-none/release/soroban_deployer_contract.wasm
```

```
target/wasm32v1-none/release/soroban_deployer_test_contract.wasm
```

## Run the contract

Before deploying the test contract with the deployer, install the test contract Wasm using the `upload` command. The `upload` command will print out the hash derived from the Wasm file which should be used by the deployer.

```sh theme={"theme":{"light":"github-light","dark":"github-dark"}}
stellar contract upload \
--wasm  contract/target/wasm32v1-none/release/soroban_deployer_test_contract.wasm \
--source-account alice \
--network testnet
```

When deploying a smart contract to the network, you must specify an identity that will be used to sign the transactions. Change the `alice` [identity] to your own.

[identity]: https://developers.stellar.org/docs/build/smart-contracts/getting-started/setup.md#configure-an-identity

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.

```sh theme={"theme":{"light":"github-light","dark":"github-dark"}}
stellar contract deploy \
  --wasm deployer/target/wasm32v1-none/release/soroban_deployer_contract.wasm \
  --source-account alice  \
  --network testnet \
  -- --admin alice
```

This will return the deployer address. For example: `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`.

```sh theme={"theme":{"light":"github-light","dark":"github-dark"}}
stellar contract invoke \
  --id CDKYZMA3OXR54YAHOQ5D4EWDFDT3ZNKKRYKQT7MGPWH22ZVD2DX2BJID \
  --source-account alice \
  --network testnet \
  -- \
  deploy \
  --salt 123 \
  --wasm_hash 6bc6d975ef99c057231481c40f69f4c2a8a89ac56e8826ef0378f8e5c6abc4be \
  --constructor_args '[{"u32":8}]'
```

The deployer contract invocation will return the Contract address (For example: `CCTVFX6BFTQHTGAHA5TY4YZQJRUKRE2RRNUTGVBNKE3PJF5C7CI53APY`) of the newly deployed test contract.

Invoke the deployed test contract using the address returned from the previous command.

```sh theme={"theme":{"light":"github-light","dark":"github-dark"}}
stellar contract invoke \
  --id CCTVFX6BFTQHTGAHA5TY4YZQJRUKRE2RRNUTGVBNKE3PJF5C7CI53APY \
  --source-account alice \
  --network testnet \
  -- \
  value
```

You should receive something like the following output:

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
8
```
