Run a Ferminux Node
ferminux-geth is a dedicated client for the Ferminux Network (ChainID 3961 / 0xF79,
coin FMX). The genesis block is baked into the binary — there is nothing to
download, no genesis.json to pass, no init step. An empty datadir joins the network.
Quickstart (zero config)
ferminux-geth
That is the whole thing. On first start you will see:
INFO Writing default Ferminux genesis block
INFO Chain ID: 3961 (ferminux)
INFO Consensus: Ethash (proof-of-work)
Genesis hash: 0x1b62e052ee210c433440b9cd21b93b3e6cdc813fe63674c842bca3967d92fadf
Bootnodes status: until the mainnet infrastructure ceremony fills in the production enodes for
boot1/boot2/boot3.ferminux.net, the built-in bootnode list is empty and a fresh node finds no peers on its own. Pass the current bootnodes explicitly (published at ferminux.net):ferminux-geth --bootnodes "enode://<key>@boot1.ferminux.net:30303"
Get the binary
Native release builds are produced for linux amd64/arm64, windows amd64 and
macos arm64 (see chain/.github/workflows/release.yml). Or build from source:
cd chain
# Go 1.18–1.20; on newer Go:
GOTOOLCHAIN=go1.20.14 make ferminux-geth # → build/bin/ferminux-geth
Docker
cd chain
docker build -t ferminux/geth:dev .
# Zero-config node; chain data persisted in a named volume
docker run -d --name ferminux-node \
-v ferminux-data:/root/.ferminux \
-p 30303:30303 -p 30303:30303/udp \
ferminux/geth:dev
The image's entrypoint is ferminux-geth; a geth symlink exists for script
compatibility. Any arguments after the image name are passed straight to the client.
GUI app
A desktop app that wraps ferminux-geth (one-click node + wallet) is planned as a separate component; check ferminux.net for downloads when it ships. Everything in this page is the CLI path and works today.
Headless server install (systemd)
scripts/install-headless.sh sets up a hardened full node on Ubuntu/Debian: a
dedicated ferminux system user, datadir /var/lib/ferminux, and a
ferminux.service systemd unit with RPC bound to localhost only.
# Full node (no mining)
sudo ./scripts/install-headless.sh
# Mining node — FMX_REWARD_ADDR is REQUIRED with --mine
sudo FMX_REWARD_ADDR=0xYourAddress ./scripts/install-headless.sh --mine
What --mine adds to the unit: --mine --miner.threads 0 --miner.etherbase $FMX_REWARD_ADDR
(--miner.threads 0 = use all CPU cores; see mining.md).
Manage it:
journalctl -fu ferminux # logs
systemctl status ferminux # health
systemctl restart ferminux
The installed unit runs:
geth --datadir /var/lib/ferminux --networkid 3961 --syncmode full \
--http --http.addr 127.0.0.1 --http.port 8545 --http.api eth,net,web3 \
--port 30303
The script currently installs against
/usr/local/bin/gethand performs an (idempotent, optional)initfromgenesis/genesis.json— with ferminux-geth theinitis unnecessary but harmless: it produces the identical chain. Place theferminux-gethbinary at/usr/local/bin/geth(or symlink it) before running.
There are also plain foreground scripts:
./scripts/start-node.sh # full node + local RPC
FMX_REWARD_ADDR=0xYou ./scripts/start-mining-cpu.sh 4 # CPU miner, 4 threads
Both honor FMX_DATADIR (default ~/.ferminux) and FMX_BOOTNODES
(comma-separated enode:// URLs).
Where your data lives
| OS | Default datadir |
|---|---|
| Linux | ~/.ferminux |
| macOS | ~/Library/Ferminux |
| Windows | %APPDATA%\Ferminux |
Inside the datadir:
| Path | Contents |
|---|---|
<datadir>/ferminux-geth/chaindata |
the chain database (instance dir follows the client name — not geth/chaindata) |
<datadir>/keystore |
your encrypted account keys — back this up |
<datadir>/geth.ipc |
IPC socket (kept as geth.ipc for tooling compatibility) |
Attach a console to a running node:
ferminux-geth attach # default datadir
ferminux-geth attach --exec 'eth.blockNumber' ~/.ferminux/geth.ipc
Flags go before the socket path — see the flag-order gotcha in troubleshooting.md.
RPC flags — and the security rules
Enable local JSON-RPC:
ferminux-geth --http --http.addr 127.0.0.1 --http.port 8545 \
--http.api eth,net,web3,txpool
WebSocket:
ferminux-geth --ws --ws.addr 127.0.0.1 --ws.port 8546 --ws.api eth,net,web3
Quick check that it is answering (expect 0xf79):
curl -s -X POST -H 'Content-Type: application/json' \
--data '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}' \
http://127.0.0.1:8545
Security — read before changing any of these flags:
- Never expose
--httppublicly without a reverse proxy. Keep--http.addr 127.0.0.1(the default). If you need remote access, put nginx/caddy with TLS, rate limits and an allowlist in front — that is exactly how the publichttps://rpc.ferminux.netendpoint is run. Binding--http.addr 0.0.0.0on an internet-facing machine invites tx spam, resource exhaustion and, if you ever unlock an account, theft. - The
personalnamespace stays off. Never addpersonal(oradmin,debug,miner) to--http.apion a reachable interface.personal_unlockAccountover HTTP is how nodes get drained. Sign transactions client-side, or use the IPC socket (geth.ipc), which is file-permission protected and local-only. --http.corsdomain '*'/--http.vhosts '*'are for local development only.- Never pass
--override.terminaltotaldifficulty— it can arm the dormant merge path on your own node. Likewise--mainnet/--sepoliaetc. still parse but are non-functional on this dedicated client; don't use them.
Verify you are on the right chain
# ChainID → 0xf79 (3961)
curl -s -X POST -H 'Content-Type: application/json' \
--data '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}' http://127.0.0.1:8545
# Genesis hash → 0x1b62e052ee210c433440b9cd21b93b3e6cdc813fe63674c842bca3967d92fadf
ferminux-geth attach --exec 'eth.getBlock(0).hash'