> For the complete documentation index, see [llms.txt](https://ibvm.gitbook.io/ibvm-doc/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ibvm.gitbook.io/ibvm-doc/technical-documentation/ibvm-node-installation-and-operations-guide.md).

# IBVM Node Installation & Operations Guide

## Overview

IBVM (International Bitcoin Virtual Machine) is a Bitcoin Layer-2 blockchain that provides EVM compatibility, fast transaction processing, and scalable smart contract execution while leveraging Bitcoin's security model. IBVM supports Solidity smart contracts and standard Ethereum development tools.

This guide explains how to install, configure, operate, and maintain an IBVM node.

## Network Information

| Parameter          | Value                                                       |
| ------------------ | ----------------------------------------------------------- |
| Network Name       | IBVM Mainnet                                                |
| Blockchain Type    | Bitcoin Layer 2                                             |
| Client             | IBVM Layer-2 v1.2.1                                         |
| Virtual Machine    | EVM Compatible                                              |
| Smart Contracts    | Solidity Compatible                                         |
| Native Token       | IBVM                                                        |
| Decimals           | 18                                                          |
| Average Block Time | 2 Seconds                                                   |
| Explorer           | [https://ibvmscan.io](https://ibvmscan.io/)                 |
| Mainnet RPC        | [https://rpc-mainnet.ibvm.io](https://rpc-mainnet.ibvm.io/) |
| GitHub             | <https://github.com/IBVM-official>                          |
| Support            | <support@ibvm.io>                                           |

### Values used in this guide

Replace these placeholders in every command below. Request the network ID, genesis file and bootnode list from the IBVM team if you don't have them.

| Placeholder        | Meaning                                                     |
| ------------------ | ----------------------------------------------------------- |
| `<NETWORK_ID>`     | IBVM network ID                                             |
| `<BOOTNODE_ENODE>` | `enode://...@IP:PORT` of an IBVM bootnode                   |
| `<NODE_IP>`        | Private IP of your server (for example your AWS private IP) |
| `<SIGNER_ADDRESS>` | Signer account address (signer nodes only)                  |

## Node Types

| Type         | Purpose                                                                              | Key flags                                   |
| ------------ | ------------------------------------------------------------------------------------ | ------------------------------------------- |
| Full node    | Follows the chain, serves recent state over RPC                                      | `--syncmode full --gcmode full`             |
| Archive node | Keeps all historical state. Required for explorers and tracing internal transactions | `--syncmode full --gcmode archive`          |
| Signer node  | Authorised Clique signer that seals new blocks                                       | `--mine --miner.etherbase ... --unlock ...` |

## Hardware Requirements

### Full Node

| Component | Minimum          |
| --------- | ---------------- |
| CPU       | 4 Cores          |
| RAM       | 8 GB             |
| Storage   | 100 GB SSD       |
| Network   | 100 Mbps         |
| OS        | Ubuntu 22.04 LTS |

### Archive Node

| Component | Minimum    |
| --------- | ---------- |
| CPU       | 8 Cores    |
| RAM       | 16 GB      |
| Storage   | 500 GB SSD |
| Network   | 100 Mbps   |

Supported operating systems: Ubuntu 20.04 / 22.04 LTS (recommended), Debian 11+, Rocky Linux 8+, AlmaLinux 8+.

## Step 1: Install Dependencies

```bash
sudo apt update && sudo apt upgrade -y
sudo apt install -y curl wget unzip git screen tmux build-essential
```

## Step 2: Install Go (1.21 or newer)

IBVM Layer-2 v1.2.1 needs Go 1.21+ to build. Check what you have:

```bash
go version
```

If Go is missing or older than 1.21:

```bash
wget https://go.dev/dl/go1.21.13.linux-amd64.tar.gz
sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf go1.21.13.linux-amd64.tar.gz
echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc
source ~/.bashrc
go version
```

## Step 3: Build IBVM Layer-2 v1.2.0

```bash
cd /opt
sudo git clone https://github.com/IBVM-official/IBVM-Layer2-Blockchain/
git checkout v1.2.1
make all
```

`make all` builds `geth` and the helper tools (including `bootnode`) into `build/bin/`. Install the binary and confirm the version:

```bash
sudo cp build/bin/geth /usr/local/bin/geth
geth version
```

The output must show `Version: 1.13.15-stable`.

{% hint style="info" %}
Instead of building, you can download the "Geth 1.13.15" linux-amd64 archive from [geth.ethereum.org/downloads](https://geth.ethereum.org/downloads).
{% endhint %}

## Step 4: Create the Node Directory

```bash
mkdir -p ~/ibvm/node1
```

Use a separate directory (datadir) for every node you run on the same server, for example `~/ibvm/node1`, `~/ibvm/node2`.

## Step 5: Initialise the Chain from the IBVM Genesis

Every IBVM node must start from the **official IBVM genesis file**. A node initialised with any other genesis creates a different chain and will never sync.

```bash
cd ~/ibvm
# place the official genesis.json here, then:
# Download genesis file from here https://assets.ibvm.io/genesis.json 
geth init --datadir node1 --state.scheme hash genesis.json
```

{% hint style="danger" %}
Run `geth init` **only once**, on a new, empty datadir. Never re-run it on a node that already has chain data, and never edit the genesis file of a running network. The chain configuration is read from the database, and changing it alters block hashes.
{% endhint %}

`--state.scheme hash` is required for archive nodes and keeps all IBVM nodes on the same storage format.

## Step 6: Start the Node

### Full node (RPC)

```bash
geth --datadir ~/ibvm/node1 \
  --networkid <NETWORK_ID> \
  --syncmode full --gcmode full --state.scheme hash \
  --port 30303 \
  --bootnodes '<BOOTNODE_ENODE>' \
  --http --http.addr <NODE_IP> --http.port 8545 \
  --http.api eth,net,web3,txpool \
  --http.vhosts '*' --http.corsdomain '*' \
  --ws --ws.addr <NODE_IP> --ws.port 8546 --ws.origins '*' \
  --ws.api eth,net,web3,txpool 
```

### Archive node (explorer / internal transactions)

```bash
geth --datadir ~/ibvm/node1 \
  --networkid <NETWORK_ID> \
  --syncmode full --gcmode archive --state.scheme hash \
  --port 30303 \
  --bootnodes '<BOOTNODE_ENODE>' \
  --http --http.addr <NODE_IP> --http.port 8545 \
  --http.api eth,net,web3,txpool,debug \
  --http.vhosts '*' --http.corsdomain '*' \
  --ws --ws.addr <NODE_IP> --ws.port 8546 --ws.origins '*' \
  --ws.api eth,net,web3,txpool,debug \
  --rpc.gascap 0
```

Notes for archive / explorer nodes:

* `debug` exposes `debug_traceTransaction`, which explorers (for example Blockscout) use with `callTracer` to show **internal transactions**.
* Internal transactions for **historical** blocks are only available on a node that has run with `--gcmode archive` since genesis. Switching an existing full node to archive requires a full resync.
* `--rpc.gascap 0` removes the gas cap on `eth_call` / `eth_estimateGas`. Without it, explorers can fail with `gas required exceeds allowance`. Set a finite value instead of `0` if the RPC is public.
* Point the explorer's trace endpoint at this archive node, not at a full or signer node.

### Flag reference

| Flag                        | Purpose                                              |
| --------------------------- | ---------------------------------------------------- |
| `--networkid`               | Must match the IBVM network ID                       |
| `--syncmode full`           | Executes every block from genesis                    |
| `--gcmode archive` / `full` | Keep all historical state / prune old state          |
| `--state.scheme hash`       | Storage scheme; required for archive mode            |
| `--bootnodes`               | Peers used to discover the network                   |
| `--http.api`, `--ws.api`    | RPC namespaces to expose. Keep to the minimum needed |
| `--rpc.gascap`              | Gas cap for `eth_call` / `eth_estimateGas`           |

## Step 7: Run geth as a Service

Run the node under a process manager so it restarts on failure and on reboot. Whichever you choose, **give geth time to shut down cleanly**. An archive node can take a minute or more to flush to disk, and a forced kill is the most common cause of database corruption.

### Option A: systemd (recommended)

Create `/etc/systemd/system/ibvm.service`:

```ini
[Unit]
Description=IBVM geth node
After=network-online.target
Wants=network-online.target

[Service]
User=ubuntu
Type=simple
ExecStart=/usr/local/bin/geth \
  --datadir /home/ubuntu/ibvm/node1 \
  --networkid <NETWORK_ID> \
  --syncmode full --gcmode archive --state.scheme hash \
  --port 30303 \
  --bootnodes <BOOTNODE_ENODE> \
  --http --http.addr <NODE_IP> --http.port 8545 \
  --http.api eth,net,web3,txpool,debug \
  --ws --ws.addr <NODE_IP> --ws.port 8546 \
  --ws.api eth,net,web3,txpool,debug
KillSignal=SIGINT
TimeoutStopSec=300
Restart=on-failure
RestartSec=5
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
```

Enable and start it:

```bash
sudo systemctl daemon-reload
sudo systemctl enable ibvm
sudo systemctl start ibvm
sudo systemctl status ibvm
journalctl -u ibvm -f
```

### Option B: PM2

Put the start command in a script, for example `start-node1.sh`:

```bash
#!/bin/bash
exec /usr/local/bin/geth --datadir /home/ubuntu/ibvm/node1 \
  --networkid <NETWORK_ID> \
  ... # remaining flags from Step 7
```

```bash
chmod +x start-node1.sh
pm2 start ./start-node1.sh --name ibvm-node1 --kill-timeout 120000
pm2 save
pm2 startup
```

The default PM2 kill timeout is 1.6 seconds, which is far too short for geth. Always pass `--kill-timeout 120000`. After changing geth flags, use `pm2 restart ibvm-node1 --update-env` (not `pm2 reload`).

### Option C: screen

```bash
screen -S node1
./start-node1.sh
# detach: Ctrl+A then D     reattach: screen -r node1
```

To stop, reattach and press **Ctrl+C once**, then wait for `Blockchain stopped` and `Database closed` in the log before closing the session.

## Step 9: Verify the Node

Attach to the console over IPC (gives access to all namespaces, including `admin` and `clique`):

```bash
geth attach ~/ibvm/node1/geth.ipc
```

```js
admin.nodeInfo.protocols.eth.genesis   // must equal the IBVM genesis hash
admin.nodeInfo.enode                   // this node's enode (share it to add as a peer)
net.peerCount                          // should be > 0
eth.syncing                            // false = fully synced
eth.blockNumber                        // should keep increasing
clique.getSigners()                    // current authorised signers
```

On a signer node, the log should show `Commit new sealing work` and `Successfully sealed new block`.

Test the RPC from another machine:

```bash
curl -s -X POST -H "Content-Type: application/json" \
  --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' \
  http://<NODE_IP>:8545
```

On an archive node, confirm internal-transaction tracing works:

```bash
curl -s -X POST -H "Content-Type: application/json" \
  --data '{"jsonrpc":"2.0","method":"debug_traceTransaction","params":["<TX_HASH>",{"tracer":"callTracer"}],"id":1}' \
  http://<NODE_IP>:8545
```

A response with a `calls` array means internal transactions can be traced.

## Adding Peers Manually

If a node has no peers, add one from the console:

```js
admin.addPeer("enode://<PUBKEY>@<PEER_IP>:30303")
```

To keep peers across restarts, list them in `--bootnodes` (comma-separated).

## External Storage

To move chain data to a larger volume:

```bash
sudo mkdir -p /mnt/gethdata
sudo mount /dev/sdb /mnt/gethdata
sudo systemctl stop ibvm            # wait for a clean shutdown
rsync -a ~/ibvm/node1/ /mnt/gethdata/node1/
```

Then change `--datadir` to `/mnt/gethdata/node1` and start the node. Add the volume to `/etc/fstab` so it mounts on boot.

## Storage Requirements

| Duration  | Full Node | Archive Node |
| --------- | --------- | ------------ |
| 3 Months  | 30-40 GB  | 100-120 GB   |
| 6 Months  | 50-70 GB  | 180-220 GB   |
| 12 Months | 100+ GB   | 400+ GB      |

Actual usage depends on network activity. Monitor free disk space; geth stops when the disk fills up.

## Backup Procedure

1. Stop the node cleanly and wait for `Database closed` in the log.
2. Back up the datadir and keys:

```bash
tar -czf node1-backup-$(date +%F).tar.gz -C ~/ibvm node1
cp -r ~/ibvm/node1/keystore ~/keystore-backup-node1
```

3. On AWS, also take an **EBS snapshot** of the data volume.
4. Store keystore backups offline and separately from the data backups.

## Firewall Configuration

| Port  | Protocol  | Purpose       | Who should reach it                |
| ----- | --------- | ------------- | ---------------------------------- |
| 30303 | TCP + UDP | P2P           | Other IBVM nodes                   |
| 8545  | TCP       | HTTP RPC      | Trusted hosts / reverse proxy only |
| 8546  | TCP       | WebSocket RPC | Trusted hosts / reverse proxy only |

```bash
sudo ufw allow 30303/tcp
sudo ufw allow 30303/udp
sudo ufw allow from <TRUSTED_IP> to any port 8545 proto tcp
sudo ufw allow from <TRUSTED_IP> to any port 8546 proto tcp
sudo ufw enable
```

On AWS, apply the same rules in the instance's **Security Group**. For private networks you can also restrict P2P to your VPC with `--netrestrict 172.31.0.0/16`.

## Troubleshooting

| Symptom                                           | Likely cause and fix                                                                                                                     |
| ------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `flag provided but not defined: -miner.gastarget` | Flag removed in v1.13.x. Delete it from the command                                                                                      |
| `net.peerCount` is 0                              | Wrong `--networkid`, wrong bootnode, or P2P port 30303 blocked. Check firewall and Security Group                                        |
| Genesis hash differs from IBVM                    | Node initialised with the wrong genesis. Wipe the datadir and re-run `geth init` with the official file                                  |
| `gas required exceeds allowance`                  | RPC gas cap too low for the call. Set `--rpc.gascap` on the node the app/explorer uses                                                   |
| `the method debug_... does not exist`             | `debug` not in `--http.api` / `--ws.api` on that node                                                                                    |
| `missing trie node` on old blocks                 | Node is not an archive node. Use a node running `--gcmode archive` from genesis                                                          |
| `ECONNREFUSED` / `EADDRNOTAVAIL`                  | RPC bound to a different IP/port than the client uses, or blocked by the firewall. Check `--http.addr`, `--http.port` and Security Group |
| Signer not sealing                                | Account not unlocked, `--mine` missing, `--miner.etherbase` wrong, or address not in `clique.getSigners()`                               |

## Security Recommendations

* Run signer nodes on private IPs only, with no public RPC.
* Never expose `admin`, `personal`, `miner` or `debug` namespaces publicly.
* Put public RPC behind an HTTPS reverse proxy (for example Nginx) with rate limiting.
* Keep keystores and password files readable only by the geth user (`chmod 600`).
* Restrict every RPC port to trusted IPs in the firewall and AWS Security Group.
* Back up node data and keystores regularly, and test restores.
* Monitor disk usage, peer count and block height.

## Official Resources

* Documentation: <https://ibvm.gitbook.io/ibvm-doc>
* Explorer: [https://ibvmscan.io](https://ibvmscan.io/)
* Mainnet RPC: [https://rpc-mainnet.ibvm.io](https://rpc-mainnet.ibvm.io/)
* GitHub: <https://github.com/IBVM-official>
* Website: [https://ibvm.io](https://ibvm.io/)
* Support: <support@ibvm.io>

Copyright © IBVM Pty Ltd. All Rights Reserved.
