Merged Mining Setup
How Merged Mining Works
Merged mining allows Bitcoin miners to simultaneously mine ELA at zero additional cost. The process:
- The ELA node creates a block template with a target hash
- That hash is embedded in the Bitcoin coinbase transaction (using magic bytes
0xFABE6D6D) - When a Bitcoin block is mined, if the hash meets ELA's difficulty, it also counts as an ELA block
- An AuxPoW proof is constructed and submitted to the ELA chain
From the miner's perspective, nothing changes; they are just mining Bitcoin. The pool infrastructure handles ELA integration transparently.
ELA Chain ID for AuxPoW: 1224
Architecture
The merged mining infrastructure uses btcpool (a fork of BTC.COM's mining pool) with Apache Kafka as the message bus:
┌──────────┐ RawGbt ┌──────────┐ StratumJob ┌──────────┐
│ gbtmaker ├────────────►│ jobmaker ├────────────────►│ sserver │
└──────────┘ └────┬─────┘ └────┬─────┘
│ │
┌──────────────┐ AuxPowBlock │ │ SolvedShare
│ nmcauxmaker ├──────────────┘ │ AuxSolvedShare
└──────────────┘ │
┌────▼─────┐
│ blkmaker │
└──────────┘
| Component | Role |
|---|---|
| gbtmaker | Polls Bitcoin node for block templates |
| nmcauxmaker | Polls ELA node for aux block templates |
| jobmaker | Combines Bitcoin + ELA templates into stratum jobs |
| sserver | Serves jobs to miners, collects shares |
| blkmaker | Detects shares meeting ELA difficulty, builds AuxPoW proofs, submits to ELA |
Prerequisites
- A running Bitcoin full node with GBT and ZMQ support
- A running ELA full node with
createauxblockandsubmitauxblockRPC methods - Apache Kafka + ZooKeeper
- btcpool compiled from the Elastos fork:
github.com/elastos/btcpool - Optional: MySQL for block/share logging
btcpool build dependencies:
sudo apt-get install -y \
build-essential cmake \
libzmq3-dev librdkafka-dev libglog-dev \
libconfig++-dev libcurl4-openssl-dev \
libssl-dev libboost-all-dev libevent-dev \
libprotobuf-dev protobuf-compiler \
libmysqlclient-dev
Build btcpool:
git clone https://github.com/elastos/btcpool.git
cd btcpool
mkdir build && cd build
cmake -DJOBS=4 -DCHAIN_TYPE=BTC -DCHAIN_SRC_ROOT=/path/to/bitcoin/src ..
make -j$(nproc)
ELA Node Configuration for Mining
Your ELA node must expose RPC and ZMQ endpoints for the mining pool:
{
"Configuration": {
"EnableRPC": true,
"RpcConfiguration": {
"User": "pool_rpc_user",
"Pass": "pool_rpc_pass",
"WhiteIPList": ["127.0.0.1", "POOL_SERVER_IP"]
},
"PowConfiguration": {
"PayToAddr": "ELA_COINBASE_ADDRESS",
"AutoMining": false
}
}
}
Ensure the ELA node is started with ZMQ block notifications enabled if supported, or use polling-only mode.
nmcauxmaker Configuration
File: nmcauxmaker.cfg
Despite the "nmc" prefix (historical; originally for Namecoin), this component works with any AuxPoW chain including Elastos.
nmcauxmaker = {
rpcinterval = 10;
file_last_rpc_call_time = "/work/btcpool/run/nmcauxmaker_lastrpccalltime.txt";
is_check_zmq = true;
payout_address = "YOUR_ELA_PAYOUT_ADDRESS";
auxpow_gw_topic = "AuxPowBlock";
};
namecoind = {
zmq_addr = "tcp://127.0.0.1:8337";
zmq_timeout = 1200;
rpc_addr = "http://127.0.0.1:20336";
rpc_userpwd = "pool_rpc_user:pool_rpc_pass";
};
kafka = {
brokers = "127.0.0.1:9092";
};
| Parameter | Description |
|---|---|
rpcinterval | Seconds between polling for new aux blocks (10 is standard) |
is_check_zmq | Verify ZMQ connection on startup |
payout_address | ELA address to receive mining rewards |
auxpow_gw_topic | Kafka topic name (must match jobmaker config) |
namecoind.zmq_addr | ELA node's ZMQ endpoint for hashblock notifications |
namecoind.rpc_addr | ELA node's JSON-RPC endpoint |
namecoind.rpc_userpwd | ELA RPC credentials in user:pass format |
The nmcauxmaker calls createauxblock on the ELA node and receives:
{
"result": {
"hash": "ae3384a9c21956efb385801ccd16e2799d3a88b4245c592e37dd0b46ea3bf0f5",
"chainid": 1224,
"previousblockhash": "ba22e44e...",
"coinbasevalue": 2500000000,
"bits": "180a7f3c",
"height": 303852
}
}
jobmaker Configuration
File: jobmaker.cfg (relevant AuxPoW sections)
jobmaker = {
auxpow_gw_topic = "AuxPowBlock";
aux_merged_mining_notify = true;
};
| Parameter | Description |
|---|---|
auxpow_gw_topic | Must match the topic in nmcauxmaker.cfg |
aux_merged_mining_notify | When true, sends new stratum jobs to miners when a new aux block template arrives |
blkmaker Configuration
File: blkmaker.cfg (relevant AuxPoW sections)
blkmaker = {
auxpow_solved_share_topic = "AuxSolvedShare";
found_aux_block_table = "found_nmc_blocks";
aux_chain_name = "ela";
};
| Parameter | Description |
|---|---|
auxpow_solved_share_topic | Kafka topic for shares meeting ELA difficulty |
found_aux_block_table | MySQL table name for logging found blocks |
aux_chain_name | Label used in database records |
Multi-Chain Merged Mining
To mine both Namecoin and Elastos simultaneously, use the Merged Mining Proxy:
┌─────────────┐
│ Namecoin │
│ Node │
└──────┬──────┘
│
┌──────────────┐ ┌─────▼──────────┐ ┌──────────┐
│ nmcauxmaker ├────►│ Merged Mining │◄────┤ Elastos │
└──────────────┘ │ Proxy │ │ Node │
└────────────────┘ └──────────┘
The proxy (from github.com/btccom/btcpool-go-modules/tree/master/mergedMiningProxy):
- Connects to each aux chain node
- Combines their block hashes into a Merkle tree
- Returns a combined
createauxblockresponse with the Merkle root - Each chain's position is determined by:
slot = chain_id % merkle_size - On
submitauxblock, extracts each chain's individual proof and submits separately
Configure nmcauxmaker to point at the proxy instead of directly at the ELA node.
Verifying Mining is Working
# Check if nmcauxmaker is polling successfully
# Look for log entries showing aux block templates received
tail -f /work/btcpool/run/nmcauxmaker/nmcauxmaker.log
# Verify Kafka topics have data
kafka-console-consumer --bootstrap-server 127.0.0.1:9092 \
--topic AuxPowBlock --from-beginning --max-messages 5
# Check for found ELA blocks in MySQL
mysql -e "SELECT * FROM found_nmc_blocks ORDER BY id DESC LIMIT 10;" pooldb
# Verify on the ELA node that blocks are being produced
node.sh ela status
Using supervisord for process management:
[program:nmcauxmaker]
command=/work/btcpool/build/nmcauxmaker -c /work/btcpool/run/nmcauxmaker.cfg -l /work/btcpool/run/
autostart=true
autorestart=true
stderr_logfile=/var/log/nmcauxmaker.err.log
stdout_logfile=/var/log/nmcauxmaker.out.log