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 for installation details.

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

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.

babylond keys add bvs-user

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.

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.

    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 to install CosmWasm.

  3. CosmWasm: Read the CosmWasm Documentation to set up the environment.

  4. Babylond: Ensure you've installed babylond command line tool

  5. Satlayer CLI: Ensure you've installed satlayer-cli

For this tutorial, you will need to install 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

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

Step 2: Move to the Contract Directory

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

Step 3: Compile the Contract:

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

The compiled WASM file will be found at:

./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

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.

  • The version installed on your system, which is easier to use during coding and testing.

Step 6: Run Tests

Execute all tests in the contract by running the following command outside of Docker:

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

./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.

On success, no error message should show up and txHash printed. This transaction hash can be used on our block explorer to view details about the transaction. (For instance: upload code tx)

❯ 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.

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

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:

❯ 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:

./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 in our blockchain explorer.

Step 3: Get contract address

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

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:

❯ 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}

If you execute the above command in macOS, it may require you input the password and then click Always Allow.

This command will return 3 txHash, use the Register bvs success txHash to get bvs_hash in tx_repsonse/events/wasm field as follows:

Alternatively, you can use the following command:

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'
❯ 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.

Please save this BVS hash somewhere as it will be used later during off-chain software configuration.

Register operator to DelegationManager and BVSDirectory

# 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

# 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 and respond_to_task tx information in our blockchain explorer.

  1. Query the contract data

./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
  1. Upgrade the contract

CosmWasm supports contract upgrade by via the migrate command. You should add migrate function in your contract like this.

You should do the following steps:

  • Upload a new contract to testnet

  • Get the code id

  • Execute the following commands:

./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.

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.

# 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.

# 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).

# 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 documentation can be applied to launch the newly configured BVS. Here, we'll present a streamlined version.

First, start Redis and the aggregator.

sudo systemctl start redis.service

cd aggregator
go run main.go

Next, run the off chain compute process.

cd offchain
go run main.go

Afterwards, start the task caller to start the BVS.

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!

Last updated