#!/usr/bin/env bash # Production Z Chain Besu bootstrap (chainId 900002) on a banking LXC or VM. # Generates IBFT2 keys once, then runs Besu with persistent data under /opt/besu-z-chain. set -euo pipefail ROOT="$(cd "$(dirname "$0")/../.." && pwd)" NETWORK_DIR="${Z_CHAIN_NETWORK_DIR:-/opt/besu-z-chain/network}" DATA_PATH="${Z_CHAIN_DATA_PATH:-/opt/besu-z-chain/data}" GENESIS_CONFIG="$ROOT/config/z-chain-network-config.json" RPC_PORT="${Z_CHAIN_RPC_PORT:-8546}" CONTAINER_NAME="${Z_CHAIN_BESU_CONTAINER:-z-chain-besu-prod}" if [[ $EUID -ne 0 ]]; then echo "Run as root on the target host (or use sudo)." exit 1 fi if ! command -v docker &>/dev/null; then echo "ERROR: docker required on production host" exit 1 fi mkdir -p "$NETWORK_DIR" "$DATA_PATH" if [[ ! -f "$NETWORK_DIR/genesis.json" ]]; then echo "Generating IBFT2 network files in $NETWORK_DIR ..." docker run --rm \ -v "$ROOT/config:/config:ro" \ -v "$NETWORK_DIR:/network" \ hyperledger/besu:latest \ operator generate-blockchain-config \ --config-file=/config/z-chain-network-config.json \ --to=/network fi docker rm -f "$CONTAINER_NAME" 2>/dev/null || true echo "Starting production Z Chain Besu on 0.0.0.0:$RPC_PORT ..." docker run -d \ --name "$CONTAINER_NAME" \ --restart unless-stopped \ -p "127.0.0.1:${RPC_PORT}:8545" \ -v "$NETWORK_DIR:/network:ro" \ -v "$DATA_PATH:/data" \ hyperledger/besu:latest \ --data-path=/data \ --genesis-file=/network/genesis.json \ --node-private-key-file=/network/keys/node1/key \ --rpc-http-enabled \ --rpc-http-api=ETH,NET,WEB3,IBFT,ADMIN \ --rpc-http-host=127.0.0.1 \ --rpc-http-port=8545 \ --host-allowlist="*" \ --min-gas-price=0 echo "" echo "Production Z Chain RPC (localhost): http://127.0.0.1:$RPC_PORT" echo "Expose via nginx/Cloudflare as https://rpc.zblockchainsystem.com" echo "Z portal: https://zblockchainsystem.com"