We have now created all the required wallets and configuration files for five validators and two users. We'll now create an L2 subnet and have four validators join it.
Step 1: Create a child subnet
We can now create a subnet under /b4 — Bitcoin Regtest. If you have not created the env variable, replace $WHITELIST with the one you created earlier.
You should see the subnet ID printed to the console. Let's save the subnet ID for later use — we will refer to it as $SUBNET_ID.
exportSUBNET_ID="the_new_subnet_id_from_terminal"
You can now start the miner helper script (as described in Helper scripts) by running the following from the bitcoin-ipc repo:
./scripts/miner.sh
All monitors should have printed the subnet create message to the console.
With the provided command, validator 1 will pay the Bitcoin fees (as the specified config file points to the provider of validator 1), but it could be any of the validators or someone else entirely.
The parameter --bottomup-check-period defines how often (in number of blocks) the subnet will create a checkpoint message. As we will discuss in the next step, withdrawals and cross-subnet transfers are included in the checkpoint message. A higher checkpoint period implies higher latency for transfers and withdrawals, a lower valuer implies more fees paid for submitting the checkpoint messages to the parent. For testing the code we recommend a value between 50 and 200.
Step 2: Update the config.toml files
We now need to add the new subnet configuration to all of the following configuration files:
~/.ipc/validator1/config.toml
~/.ipc/validator2/config.toml
~/.ipc/validator3/config.toml
~/.ipc/validator4/config.toml
~/.ipc/validator5/config.toml
~/.ipc/user1/config.toml
~/.ipc/user2/config.toml
~/.ipc/config.toml
It might be easier to leave those files open in an editor, so we can modify them later when we create a second subnet.
A subnet configuration looks as follows. For ease of use, each config.toml file already contains the entry — you only have to replace/b4/t410fyi77izvsakigfjnocb7f3hm52bjdeb76jayo4ti with your SubnetID.
The ETH addresses for gateway_addr and registry_addr used when they are deployed in genesis in a child subnet by Fendermint are 0x77aa40b105843728088c0132e43fc44348881da8 and 0x74539671a1d2f1c8f200826baba665179f53a1b7, respectively, so no need to change them.
The configuration files may contain multiple [[subnets]] entries.
Notice that each validator's config.toml files uses a different port in the provider_http field. This is because each validator interacts with its own docker container. Users interact with the container of validator 1.
Let's have four validators join the subnet with some initial collateral.
Let's include the join transactions in the blockchain by mining a block (not needed if you are running the miner.sh script).
We should see the monitors print the join messages to the console, and also reporting that the subnet has been bootstrapped, like so:
The --backup-address will be used to the return the collateral when the validator leaves the subnet.
Step 4: Fund the validators
It is crucial that a validator funds itself in the subnet before deploying the infrastructure. This because some actors (smart contracts, in the language of IPC) are initialized when the validator is funded. Without these actors the subnet will still make progress, but certain functionalities (such as the top-down messaging) will not work. Hence, please make sure you fund the validators before proceeding to the next step.
All validators need to have some balance in the subnet, as they use it to pay transaction fees. Let's fund their accounts with wBTC.
Make sure you mine a block (not needed if you are running the miner.sh script).
[2025-05-12T10:41:29Z INFO monitor] Processed JoinSubnet for Subnet ID: /b4/t410fyi77izvsakigfjnocb7f3hm52bjdeb76jayo4ti Validator XPK: 851c1bda327584479e98a7c28ea7adc097d290efd105310bcf714231bb99faf4 Collateral: 1.10000000 BTC
[2025-05-12T10:41:29Z INFO monitor] Subnet ID: /b4/t410fyi77izvsakigfjnocb7f3hm52bjdeb76jayo4ti has been bootstrapped
ipc-cli --config-path ~/.ipc/validator1/config.toml cross-msg fund --subnet=$SUBNET_ID btc --to $IPC_ADDRESS_OF_VALIDATOR_1 210000000
ipc-cli --config-path ~/.ipc/validator2/config.toml cross-msg fund --subnet=$SUBNET_ID btc --to $IPC_ADDRESS_OF_VALIDATOR_2 220000000
ipc-cli --config-path ~/.ipc/validator3/config.toml cross-msg fund --subnet=$SUBNET_ID btc --to $IPC_ADDRESS_OF_VALIDATOR_3 230000000
ipc-cli --config-path ~/.ipc/validator4/config.toml cross-msg fund --subnet=$SUBNET_ID btc --to $IPC_ADDRESS_OF_VALIDATOR_4 240000000