Skip to main content
MAIN CHAIN

Merged Mining Setup

How Merged Mining Works

Merged mining allows Bitcoin miners to simultaneously mine ELA at zero additional cost. The process:

  1. The ELA node creates a block template with a target hash
  2. That hash is embedded in the Bitcoin coinbase transaction (using magic bytes 0xFABE6D6D)
  3. When a Bitcoin block is mined, if the hash meets ELA's difficulty, it also counts as an ELA block
  4. 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 │
└──────────┘
ComponentRole
gbtmakerPolls Bitcoin node for block templates
nmcauxmakerPolls ELA node for aux block templates
jobmakerCombines Bitcoin + ELA templates into stratum jobs
sserverServes jobs to miners, collects shares
blkmakerDetects 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 createauxblock and submitauxblock RPC 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";
};
ParameterDescription
rpcintervalSeconds between polling for new aux blocks (10 is standard)
is_check_zmqVerify ZMQ connection on startup
payout_addressELA address to receive mining rewards
auxpow_gw_topicKafka topic name (must match jobmaker config)
namecoind.zmq_addrELA node's ZMQ endpoint for hashblock notifications
namecoind.rpc_addrELA node's JSON-RPC endpoint
namecoind.rpc_userpwdELA 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;
};
ParameterDescription
auxpow_gw_topicMust match the topic in nmcauxmaker.cfg
aux_merged_mining_notifyWhen 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";
};
ParameterDescription
auxpow_solved_share_topicKafka topic for shares meeting ELA difficulty
found_aux_block_tableMySQL table name for logging found blocks
aux_chain_nameLabel 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):

  1. Connects to each aux chain node
  2. Combines their block hashes into a Merkle tree
  3. Returns a combined createauxblock response with the Merkle root
  4. Each chain's position is determined by: slot = chain_id % merkle_size
  5. 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