# Subnet creation

To create a subnet, first connect to the `bitcoin-ipc` container running:

```bash
docker exec -it bitcoin-ipc bash
```

Then run:

```bash
# from inside the container
/usr/local/bin/bootstrap_subnet_a_from_container.sh
```

This is the `scripts/bootstrap_subnet_a_from_container.sh` script from the `bitcoin-ipc` repo, which has been mounted in the container for convenience.

It does the following:

1. It submits to bitcoin-core all required transactions to create a subnet and to join and fund four validators. &#x20;
2. It updates the `config.json` files of all validators in the `/root/.ipc` directory of the container.&#x20;
3. It prints, among others, the `SubnetID` of the newly created subnet — it is a good idea to export it to an env variable.

{% hint style="info" %}
Before running the previous command, you can start terminal(s) watching the logs of the Monitor and Provider for some validators, as explained in [optional-helper-scripts](https://bitcoin-scaling-labs-docs.gitbook.io/ipc-btc-scaling-docs/user-guide-for-using-subnets/optional-helper-scripts "mention"). This way you can see what is being writen and read from Bitcoin in real time.
{% endhint %}

***

## Alternative: Install on the host machine

If in page [installation](https://bitcoin-scaling-labs-docs.gitbook.io/ipc-btc-scaling-docs/user-guide-for-using-subnets/installation "mention") you chose the alternative deployment — hence `bitcoin-core` , the monitors and providers, and `ipc-cli` are running on your host machine — then you **must** also use this alternative approach here to create a child subnet.

Even if you used the default Docker-based deployment, you still have the option to use this alternative approach here to create a child subnet. In that case, you need to run all following commands from inside the `bitcoin-ipc` container — the `ipc` and `bitcoin-ipc` repos can be found in the `/root/workspace` directory.

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

```bash
ipc-cli --config-path ~/.ipc/validator1/config.toml subnet create \
	--parent /b4 --min-validators 4 --bottomup-check-period 60 \
	btc --min-validator-stake 100000000 --min-cross-msg-fee 10 \
	--validator-whitelist $WHITELIST
```

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

```sh
export SUBNET_ID="the_new_subnet_id_from_terminal"
```

You can now start the *miner* helper script (as described in [optional-helper-scripts](https://bitcoin-scaling-labs-docs.gitbook.io/ipc-btc-scaling-docs/user-guide-for-using-subnets/optional-helper-scripts "mention")) by running the following **from the bitcoin-ipc repo**:

```sh
./scripts/miner.sh
```

All monitors should have printed the subnet create message to the console.

{% hint style="success" %}

* 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.
  {% endhint %}

### 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`&#x20;
* `~/.ipc/validator5/config.toml`&#x20;
* `~/.ipc/user1/config.toml`&#x20;
* `~/.ipc/user2/config.toml`&#x20;
* `~/.ipc/config.toml`&#x20;

It might be easier to leave those files open in an editor, so we can modify them later when we create a second subnet.&#x20;

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.&#x20;

```toml
# Subnet A
[[subnets]]
id = "/b4/t410fyi77izvsakigfjnocb7f3hm52bjdeb76jayo4ti"

[subnets.config]
network_type = "fevm"
provider_http = "http://localhost:8845/"
gateway_addr = "0x77aa40b105843728088c0132e43fc44348881da8"
registry_addr = "0x74539671a1d2f1c8f200826baba665179f53a1b7"
```

{% hint style="success" %}

* 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.
* We update the config file of validator 5 already at this step. We will only use that validator at [publish-your-docs-2](https://bitcoin-scaling-labs-docs.gitbook.io/ipc-btc-scaling-docs/user-guide-for-using-subnets/publish-your-docs-2 "mention").
  {% endhint %}

### Step 3: Join the subnet

Let's have four validators join the subnet with some initial collateral.

{% code overflow="wrap" %}

```sh
ipc-cli --config-path ~/.ipc/validator1/config.toml subnet join --from $IPC_ADDRESS_OF_VALIDATOR_1 --subnet $SUBNET_ID btc --collateral=200000000 --ip 66.222.44.55:8080 --backup-address "$(bitcoin-cli --rpcwallet=validator1 getnewaddress)"

ipc-cli --config-path ~/.ipc/validator2/config.toml subnet join --from $IPC_ADDRESS_OF_VALIDATOR_2 --subnet $SUBNET_ID btc --collateral=110000000 --ip 66.222.44.55:8081 --backup-address "$(bitcoin-cli --rpcwallet=validator2 getnewaddress)"

ipc-cli --config-path ~/.ipc/validator3/config.toml subnet join --from $IPC_ADDRESS_OF_VALIDATOR_3 --subnet $SUBNET_ID btc --collateral=150000000 --ip 66.222.44.55:8082 --backup-address "$(bitcoin-cli --rpcwallet=validator3 getnewaddress)"

ipc-cli --config-path ~/.ipc/validator4/config.toml subnet join --from $IPC_ADDRESS_OF_VALIDATOR_4 --subnet $SUBNET_ID btc --collateral=180000000 --ip 66.222.44.55:8083 --backup-address "$(bitcoin-cli --rpcwallet=validator4 getnewaddress)"
```

{% endcode %}

Let's include the join transactions in the blockchain by mining a block (not needed if you are running the `miner.sh`  script).&#x20;

```sh
bitcoin-cli generatetoaddress 1 "$(bitcoin-cli --rpcwallet=default getnewaddress)"
```

We should see the monitors print the join messages to the console, and also reporting that the subnet has been bootstrapped, like so:

{% code overflow="wrap" %}

```log
[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
```

{% endcode %}

{% hint style="success" %}
The `--backup-address` will be used to the return the collateral when the validator leaves the subnet.
{% endhint %}

### Step 4: Fund the validators

{% hint style="warning" %}
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.
{% endhint %}

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.

{% code overflow="wrap" %}

```sh
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
```

{% endcode %}

Make sure you mine a block (not needed if you are running the `miner.sh`  script).

```bash
bitcoin-cli generatetoaddress 1 "$(bitcoin-cli --rpcwallet=default getnewaddress)"
```

You should see the logs being printed, like so:

{% code overflow="wrap" %}

```log
[2025-05-12T10:41:29Z INFO  monitor] Processed FundSubnet for Subnet ID: /b4/t410fyi77izvsakigfjnocb7f3hm52bjdeb76jayo4ti Address: 0x27B60D9f71D6806cCa7D5A92b391093FE100f8e8 Amount: 2.40000000 BTC
```

{% endcode %}
