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
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
Rust: Ensure you've installed Rust in your computer.
Install Rust by https://rustup.rs/.
Docker: Docker is used to compile CosmWasm contract. You should install it in your computer.
Read this doc to install CosmWasm.
CosmWasm: Read the CosmWasm Documentation to set up the environment.
Babylond: Ensure you've installed
babylond
command line toolSee babylon guide
Satlayer CLI: Ensure you've installed
satlayer-cli
See our satlayer-cli guide
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}
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.
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.
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.
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
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
Was this helpful?