Node Configuration
Production-ready configuration for a BESC Hyperchain full node. Copy this directly to /etc/besu/node-config.toml and replace YOUR_PUBLIC_IP with your server's public IP address.
Permissioning Contract — Do Not Remove
BESC Hyperchain validators enforce the on-chain AccountPermissioning contract at the network level. Every validator node checks this contract before accepting any transaction from a peer.
If your node does not have permissions-accounts-contract-enabled=true and the correct contract address configured, your node will not function on the network. Transactions submitted to your RPC will enter your local pool but every validator will silently drop them — nothing will ever confirm. This is not optional and cannot be worked around.
The current live contract address is: 0x4A7A1400fD67cCE15C87905e6953c2A9d8336D0C
# ─── Data ────────────────────────────────────────────────────────────────────
data-path="/var/lib/besu-node"
genesis-file="/etc/besu/genesis.json"
# ─── P2P Network ─────────────────────────────────────────────────────────────
p2p-host="YOUR_PUBLIC_IP"
p2p-port=30303
bootnodes=[
"enode://427acb14e865e4dd2400e6113509e1157ca53fb5bee2ed925c86de4353491e304e8ce9b4f5c9665b35d453fb38fdfc98ba3f00f7ef95af6115e08f5156fddbe6@202.143.109.9:30303"
]
host-allowlist=["*"]
# ─── HTTP RPC ─────────────────────────────────────────────────────────────────
# Bind to localhost — nginx terminates SSL and proxies requests
rpc-http-enabled=true
rpc-http-host="127.0.0.1"
rpc-http-port=8545
rpc-http-cors-origins=["all"]
rpc-http-api=["ETH","NET","WEB3","TXPOOL","IBFT","DEBUG","TRACE"]
rpc-http-max-active-connections=500
# ─── WebSocket RPC ───────────────────────────────────────────────────────────
rpc-ws-enabled=true
rpc-ws-host="127.0.0.1"
rpc-ws-port=8546
rpc-ws-api=["ETH","NET","WEB3","TXPOOL","IBFT"]
# ─── Transaction Pool ────────────────────────────────────────────────────────
tx-pool-max-size=4096
# ─── Gas ─────────────────────────────────────────────────────────────────────
min-gas-price=1000000000000
api-gas-price-max=25809520000000
# ─── Performance ─────────────────────────────────────────────────────────────
auto-log-bloom-caching-enabled=true
# ─── Permissioning — REQUIRED, DO NOT REMOVE ─────────────────────────────────
# All 4 BESC Hyperchain validators check this contract before accepting any
# transaction from a peer node. Without this, your transactions will never
# confirm regardless of gas, nonce, or balance.
permissions-accounts-contract-enabled=true
permissions-accounts-contract-address="0x4A7A1400fD67cCE15C87905e6953c2A9d8336D0C"
logging="INFO"Systemd Service
cat > /etc/systemd/system/besu-node.service << 'EOF'
[Unit]
Description=BESC Hyperchain Full Node (Besu 23.7.3)
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=root
Environment=JAVA_OPTS=-Xms4g -Xmx16g
Environment=LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libjemalloc.so.2
ExecStart=/usr/local/besu-23.7.3/bin/besu \
--config-file=/etc/besu/node-config.toml \
--rpc-max-logs-range=20000
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable besu-node.service
systemctl start besu-node.serviceNginx Reverse Proxy
server {
server_name rpc.yourdomain.com;
location / {
proxy_pass http://127.0.0.1:8545;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
add_header Access-Control-Allow-Origin * always;
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS" always;
add_header Access-Control-Allow-Headers "Content-Type" always;
proxy_read_timeout 300;
}
location /ws {
proxy_pass http://127.0.0.1:8546;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/rpc.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/rpc.yourdomain.com/privkey.pem;
}Verify Node Health
# Current block
curl -s -X POST http://127.0.0.1:8545 \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' \
| python3 -c "import sys,json; r=json.load(sys.stdin); print('Block:', int(r['result'],16))"
# Peer count (expect 4–6)
curl -s -X POST http://127.0.0.1:8545 \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"net_peerCount","params":[],"id":1}'
# Txpool status (maxSize must be 4096 — if 0, permissioning is misconfigured)
curl -s -X POST http://127.0.0.1:8545 \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"txpool_besuStatistics","params":[],"id":1}'A healthy node has 4–6 peers, imports a new block every 3 seconds, and txpool_besuStatistics returns maxSize: 4096. If maxSize shows 0, your permissioning config is missing or the contract address is wrong — transactions will not confirm.
