# Deploying a BVS

This section guides you through the steps needed to deploy your custom Hello World BVS from scratch, including setting up the required environment, building your contract, and utilizing CLI commands efficiently to modify and inspect your BVS deployment.

## Setting up wallets

At a minimum, you'll need four wallets, which we will name: `bvs-owner`, `bvs-operator`, `bvs-aggregator`.

The easiest way to create these wallets is through the **babylon** command. Please refer to our [babylon command guide](https://docs.satlayer.xyz/bvs-developers-1/developer-toolbox/babylon-cli) for installation details.&#x20;

To create the wallets, run the following commands in a terminal:

```bash
babylond keys add bvs-owner
babylond keys add bvs-operator
babylond keys add bvs-aggregator
```

Optionally, you can create a `bvs-user` wallet if desired.&#x20;

```bash
babylond keys add bvs-user
```

{% hint style="info" %}
However, for development purposes, you can use the operator account, which makes following this guide much easier as it eliminates the need to establish one additional account.

Please note that you should not use the operator account as a user account in real deployments.
{% endhint %}

Next, fund each account with tokens to cover gas and fees in the later steps.

**NOTICE:** Ensure that your keys have enough tokens to send transactions and register the BVS/Operator.

## Build and deploy the BVS Contract

### Prerequisites

1. Rust: Ensure you've installed Rust in your computer.&#x20;
   1. Install Rust by <https://rustup.rs/>.
2. Docker: Docker is used to compile CosmWasm contract. You should install it in your computer.
   1. Read this [doc](https://docs.docker.com/engine/install/) to install CosmWasm.
3. CosmWasm: Read the [CosmWasm Documentation](https://docs.cosmwasm.com/core/installation) to set up the environment.
4. Babylond: Ensure you've installed `babylond` command line tool &#x20;
   1. See [babylon guide](https://docs.satlayer.xyz/bvs-developers-1/developer-toolbox/babylon-cli)
5. Satlayer CLI: Ensure you've installed `satlayer-cli`&#x20;
   1. See our [satlayer-cli guide](https://docs.satlayer.xyz/bvs-developers-1/developer-toolbox/satlayer-cli)

For this tutorial, you will need to install [**jq** ](https://jqlang.github.io/jq/)since we use it to extract information from the JSON responses returned by Babylon nodes.

### Build Hello World BVS Contract

Here are the steps to clone the repository, compile the contract, and run tests:

#### Step 1: Clone the Repository

```bash
git clone https://github.com/satlayer/devnet-hello-world-bvs.git
```

#### Step 2: Move to the Contract Directory

```bash
cd hello-world-avb/contract/bvs-squaring
```

#### Step 3: Compile the Contract:

```bash
docker run --rm -v "$(pwd)":/code --mount type=volume,source="$(basename "$(pwd)")_cache",target=/target --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry cosmwasm/optimizer:0.16.0
```

#### Step 4: Locate the Compiled WASM File

&#x20;The compiled WASM file will be found at:

```bash
./hello-world-bvs/contract/bvs-squaring/artifacts/bvs_squaring.wasm
```

The `checksums.txt` file contains the SHA256 hash of the WASM file.

#### **Step 5: Install Rust**

&#x20;It's recommended to have both versions of Rust:

* The version provided in Docker  have optimizations to help CosmWasm reduce it's size and gas cost.&#x20;
* The version installed on your system, which is easier to use during coding and testing.

**Step 6: Run Tests**

&#x20;Execute all tests in the contract by running the following command outside of Docker:

```bash
cargo test
```

Make sure all tests pass before proceeding with the next steps.

### Deploying Hello World BVS Contract

#### Step 1: Upload the contract to Babylon Testnet

```sh
./babylond tx wasm store /path/to/your/devnet-hello-world-bvs/contract/bvs-squaring/artifacts/bvs_squaring.wasm --from=bvs-owner --gas=auto --gas-prices=1ubbn --gas-adjustment=1.3 --chain-id=sat-bbn-testnet1 -b=sync --yes --log_format=json --node https://rpc.sat-bbn-testnet1.satlayer.net
```

The following is an example output of the command.&#x20;

On success, no error message should show up and `txHash` printed. This transaction hash can be used on [our block explorer](https://devnet.satlayer.xyz) to view details about the transaction. (For instance: [upload code tx](https://devnet.satlayer.xyz/satlayer-babylon-testnet/tx/4F77EF0F2CE6E1FB00B96B138CDB4B38271F3CAD8C7B99665BA6622F6CFF27EF))

```bash
❯ babylond tx wasm store /path/to/your/bvs_squaring.wasm --from=bvs-owner --gas=auto --gas-prices=1ubbn --gas-adjustment=1.3 --chain-id=sat-bbn-testnet1 -b=sync --yes --log_format=json --node https://rpc.sat-bbn-testnet1.satlayer.net
gas estimate: 1987596
code: 44
...
txhash: 4F77EF0F2CE6E1FB00B96B138CDB4B38271F3CAD8C7B99665BA6622F6CFF27EF
```

`code_id` can be acquired from the explorer by scrolling near the end of the JSON section. Next, find "attributes". In this case, our `code_id` is 44.

<figure><img src="https://956158124-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FM4kTGNZNYF9sQa92jm8x%2Fuploads%2FtSzp927cmYX4uxl1eDul%2Fimage.png?alt=media&#x26;token=9ac8e520-e13f-405b-9cf0-c22436dfae29" alt=""><figcaption></figcaption></figure>

Alternatively, you can use the following command to query and extract `code_id` directly from the node.

```bash
curl -s https://lcd3.sat-bbn-testnet1.satlayer.net/cosmos/tx/v1beta1/txs/${TX_HASH} | jq '.tx_response.events.[] | select(.type == "store_code").attributes.[] | select(.key == "code_id").value' | sed 's/"//g'
```

For example:&#x20;

```bash
❯ curl -s https://lcd3.sat-bbn-testnet1.satlayer.net/cosmos/tx/v1beta1/txs/4F77EF0F2CE6E1FB00B96B138CDB4B38271F3CAD8C7B99665BA6622F6CFF27EF | jq '.tx_response.events.[] | select(.type == "store_code").attributes.[] | select(.key == "code_id").value' | sed 's/"//g'
44
```

#### Step 2: Instantiate the contract:

```sh
./babylond tx wasm instantiate ${code_id} '{"aggregator": "<address of bvs-aggregator>", "state_bank": "bbn1h9zjs2zr2xvnpngm9ck8ja7lz2qdt5mcw55ud7wkteycvn7aa4pqpghx2q", "bvs_driver": "bbn18x5lx5dda7896u074329fjk4sflpr65s036gva65m4phavsvs3rqk5e59c"}' --from={your_wallet} --no-admin --label="bvs" --gas=auto --gas-prices=1ubbn --gas-adjustment=1.3 --chain-id=sat-bbn-testnet1 -b=sync --yes --log_format=json --node https://rpc.sat-bbn-testnet1.satlayer.net
```

You can click this link to view the [instantiate tx hash](https://devnet.satlayer.xyz/satlayer-babylon-testnet/tx/2EE9A2BB380E1DAAA35728AE5D5899536A53C841F3A9DE53D53A79A144B82CFB) in our blockchain explorer.

#### Step 3: Get contract address

The contract address can be acquired by an API call to the node.

```bash
curl -s -X GET "https://lcd1.sat-bbn-testnet1.satlayer.net/cosmwasm/wasm/v1/code/{code_id}/contracts" -H "accept: application/json" | jq -r '.contracts[-1]'
```

For example:

```bash
❯ curl -s -X GET "https://lcd1.sat-bbn-testnet1.satlayer.net/cosmwasm/wasm/v1/code/44/contracts" -H "accept: application/json" | jq -r '.contracts[-1]'
bbn1csgvsdqy3klswqzu37t9as895s54a2d0hh8ectwqrvnf3musmc3s6zzn4d
```

#### Step 4: Register the BVS contract to BVS directory

```
./satlayer-cli directory reg-bvs bvs-owner ${contract_address}
```

{% hint style="info" %}
If you execute the above command in macOS, it may require you input the password and then click **Always Allow**.

&#x20;                             ![](https://956158124-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FM4kTGNZNYF9sQa92jm8x%2Fuploads%2FzQtAhHi5mr10o89RbJZS%2Fimage.png?alt=media\&token=1a374371-1741-4836-8747-bd2bb40de2e1)
{% endhint %}

This command will return 3 txHash, use the [`Register bvs success txHash`](https://devnet.satlayer.xyz/satlayer-babylon-testnet/tx/D101B4362D4A05EFD424AF0979CF54FAD93C11FAAE2C3719DA858ADC582469CC) to get `bvs_hash` in `tx_repsonse/events/wasm` field as follows:

<figure><img src="https://956158124-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FM4kTGNZNYF9sQa92jm8x%2Fuploads%2FclnvwLQZzO5Di1Wk3AhQ%2Fimage.png?alt=media&#x26;token=1baefe62-c610-4660-8880-6b589389febb" alt="" width="563"><figcaption><p>bvs_hash</p></figcaption></figure>

Alternatively, you can use the following command:

```bash
curl -s https://lcd3.sat-bbn-testnet1.satlayer.net/cosmos/tx/v1beta1/txs/${TX_HASH} | jq '.tx_response.events.[] | select(.type == "wasm").attributes.[] | select(.key == "bvs_hash").value' | sed 's/"//g'
```

```bash
❯ curl -s https://lcd3.sat-bbn-testnet1.satlayer.net/cosmos/tx/v1beta1/txs/D101B4362D4A05EFD424AF0979CF54FAD93C11FAAE2C3719DA858ADC582469CC | jq '.tx_response.events.[] | select(.type == "wasm").attributes.[] | select(.key == "bvs_hash").value' | sed 's/"//g'
40ec465b57ea30cbf7045f423731830f31d7aa56bf9fa6e4b20cae11309b3d18
```

For example, the `40ec465b57ea30cbf7045f423731830f31d7aa56bf9fa6e4b20cae11309b3d18` is our BVS hash.&#x20;

{% hint style="info" %}
Please save this BVS hash somewhere as it will be used later during off-chain software configuration.
{% endhint %}

## Register operator to DelegationManager and BVSDirectory

```bash
# bvs-approver is an optional address. If you don't use it, you don't need to write it.
./satlayer-cli delegation reg-operator bvs-operator [bvs-approver]
./satlayer-cli directory reg-operator bvs-operator
```

The approver has no active role in the operation of a BVS (but in accepting stakes from stakers). Approver address is optional, if you don't it, don't need to write it.

#### Manual interaction with the BVS

If you'd like to delve into the specifics of the BVS, here are instructions for manually interacting with it through the command line. However, we DO NOT anticipate that most users will require this.

1. Execute the contract

```sh
# create new task
./babylond tx wasm execute ${contract_address} '{"create_new_task": {"input": 10}}' --from=wallet --gas=auto --gas-prices=1ubbn --gas-adjustment=1.3 --chain-id=sat-bbn-testnet1 -b=sync --yes --log_format=json --node https://rpc.sat-bbn-testnet1.satlayer.net

# respond to task
./babylond tx wasm execute ${contract_address} '{"respond_to_task": {"task_id": 10, "result": 1}}' --from=bvs-aggregator --gas=auto --gas-prices=1ubbn --gas-adjustment=1.3 --chain-id=sat-bbn-testnet1 -b=sync --yes --log_format=json --node https://rpc.sat-bbn-testnet1.satlayer.net
```

In actual, you don't need to manual to respond to task, because it's called by aggregator program automatically. You can view the [create\_new\_task](https://devnet.satlayer.xyz/satlayer-babylon-testnet/tx/63D0279B3D2232A04C82160EC4A1573881D778CB727386437565D4560AED2B69) and [respond\_to\_task](https://devnet.satlayer.xyz/satlayer-babylon-testnet/tx/758220E41D01C99F3ABCC3D22B2AE885A1612ABCD095CDAA8C094C766654A45D) tx information in our blockchain explorer.

2. Query the contract data

```sh
./babylond query wasm contract-state smart ${contract_address} '{"get_task_input": {"task_id": 10}}' --log_format=json --node https://rpc.sat-bbn-testnet1.satlayer.net

./babylond query wasm contract-state smart ${contract_address} '{"get_task_result": {"task_id": 10}}' --log_format=json --node https://rpc.sat-bbn-testnet1.satlayer.net
```

3. Upgrade the contract

CosmWasm supports contract upgrade by via the migrate command. You should add `migrate` function in your contract like [this](https://github.com/satlayer/satlayer-core/blob/main/contracts/bvs-directory/src/contract.rs#L452).&#x20;

You should do the following steps:

* Upload a new contract to testnet
* Get the code id
* Execute the following commands:

```sh
./babylond tx wasm migrate ${contract_address} ${new_code_id} '{"migrate":{}}' --from wallet --gas-prices 1ubbn --gas auto --gas-adjustment 1.3 --chain-id sat-bbn-testnet1 -b=sync --yes --log_format=json --node https://rpc.sat-bbn-testnet1.satlayer.net
```

In addition, you should set `--admin` when you execute first `instantiate` command. This helps upgrade the contract without changing contract address.

## Pointing off-chain programs to the new BVS

With the BVS contract uploaded and instantiated, you can now modify the Hello World BVS to point at your contracts and aggregator.&#x20;

Point the `bvsHash` to the BVS hash you get from the above contract deployment step. Please make sure to change the owner settings to use the `bvs-aggregator` key you have created earlier.

```toml
# aggregator/env.toml

# Change the BVS hash to the one you got from deployment
[chain]
bvsHash = "<your-bvs-hash-here>" # bvs unique id

# Set keyring to "os" to as babylond by default stores keys in the OS's key storage
[owner]
keyringBackend = "os"
keyName = "bvs-aggregator"
```

The same change is needed for `bvs_offchain/env.toml`. But this time point it towards the operator.

```toml
# offchain/env.toml

[chain]
bvsHash = "<your-bvs-hash-here>" # bvs unique id

[owner]
keyringBackend = "os"
keyName = "bvs-operator"
```

Now, modify `task/env.toml` to point it to the `bvs-user` account (or use the operator account if you decided to skip that).

```toml
# task/env.toml

[chain]
bvsHash = "<your-bvs-hash-here>" # bvs unique id

[owner]
keyringBackend = "os"
keyName = "bvs-user"
```

## Running the BVS programs

You should firstly edit `go.mod` in `devnet-hello-world-bvs` to your cloned `satlayer-api` lib path:

```
# Modify go.mod to as satlayer-api is not public yet (will be!)
echo "\nreplace github.com/satlayer/satlayer-api v0.4.0 => /path/to/your/clone/of/devnet-satlayer-api" >> go.mod
```

The same approach outlined in the [Hello World BVS](https://docs.satlayer.xyz/bvs-developers-1/running-the-bvs#running-hello-world) documentation can be applied to launch the newly configured BVS. Here, we'll present a streamlined version.

First, start `Redis` and the aggregator.

```bash
sudo systemctl start redis.service

cd aggregator
go run main.go
```

Next, run the off chain compute process.&#x20;

```bash
cd offchain
go run main.go
```

Afterwards, start the task caller to start the BVS.

```bash
cd task
go run main.go caller
```

You should start seeing tasks and results appearing after a few seconds. \
\
Congratulations, you've successfully deployed your own BVS!
