The following instructions describe installing Miner ID using tools available in most mainstream Linux distributions. We assume you use a Bourne-like shell such as bash.
The BRFC (Bitcoin Request For Comment) specification can be found here.
The open source code of the implementation can be found here.
For support and general discussion of both standards and reference implementations please join the following telegram group.
For development, you will only need Node.js (minimum 10.12.0) and a node global package, NPM, installed in your environment.
  • Node installation on Windows
Just go on official Node.js website and download the installer. Also, be sure to have git available in your PATH, npm might need it (You can find git here).
  • Node installation on Ubuntu
You can install nodejs and npm easily with apt install, just run the following commands.
$ sudo apt install nodejs
$ sudo apt install npm
  • Other Operating Systems
You can find more information about the installation on the official Node.js website and the official NPM website.
$ git clone
$ cd minerid-reference
$ npm install
Create a config.json and edit it with your settings:
  • change port
  • change minerIdDataPath which stores user's miner IDs
  • change keystore which stores miner ID private keys
  • change network (mainnet="livenet" | testnet="testnet" | regtest="regtest")
  • change Bitcoin RPC parameters:
  • rpcHost
  • rpcPort
  • rpcUser
  • rpcPassword
To run API server:
$ npm start
To run CLI:
$ npm run cli
$ npm test
You can build the image yourself with your own modifications or own configurations.
$ docker build . -t minerid_reference:1.1.1
You can also pull it from the public Docker Hub repository for Miner ID here.
$ docker pull bitcoinsv/minerid:1.1.1
Example docker-compose file:
version: "3.8"
image: bitcoinsv/minerid:1.1.1
- 9002:9002
restart: always
"bitcoin": {
"network": "regtest"
- minerid:/root/.keystore
- minerid:/root/.minerid-client
external: false
Since Miner ID is essentially a service built around a private key (Miner ID) we are running the container with volumes in order to avoid the situation where the container falls over for some reason and the private key is lost. In the environment variables, we are specifying which network (livenet (or mainnet), testnet, or regtest) and what Bitcoin node RPC parameters and credentials to use by passing them to NODE_CONFIG.
Once the docker container is running, you will need to setup and configure your Miner ID by generating a Miner ID private key as well as setting up your Validity Check Transaction output (VCTx). You can do that using docker exec:
$ docker exec -it <CONTAINER> bash
[email protected]:/app#
Then run the cli commands to setup and configure the above:
[email protected]:/app# npm run cli -- generateminerid --name testMiner
[email protected]:/app# npm run cli -- generatevctx --name testMiner
If you are running on livenet (mainnet), follow the instructions to fund your VCTx.
Once your Miner ID service is setup and running, you will need to call its exposed API from your pool software to include Miner ID in your coinbase transactions. You will also need to call it from mAPI if you want to sign your mAPI responses. The Miner ID API is defined here as well as below:
The REST API has 4 endpoints:
1. GET /opreturn/:alias/:blockHeight([0-9]+)
alias: Miner ID alias blockHeight: block height which Miner ID document is created for/at
returns Miner ID output (locking) script hex string for an alias Miner ID at height blockHeight
2. POST /coinbase2
"blockHeight": number,
"alias": string,
"coinbase2": string,
"jobData": {
"miningCandidate": {},
"getInfo": {},
"feeSpec": {}
returns updated coinbase2 with the Miner ID output included
Height of the block which the coinbase transaction will be in
Alias of the Miner ID
Second part of the coinbase (coinb2) as shown in the stratum protocol
Data specific to a mining job to be added to the Miner ID coinbase document throught the extensions
BitCoin RPC getminingcandidate response
BitCoin RPC getinfo response
mAPI default fees
Note: The coinbase transaction is split up in the stratum protocol as follows:
cb tx
"blockHeight": 100,
"alias": "testMiner",
"coinbase2": "ffffffff011a0a5325000000001976a9145deb9155942e7d38febc15de8870222fd24d080e88ac00000000",
"jobData": {
"miningCandidate": {
"id": "e706b0e6-793b-448f-a1ae-8ef54459eb72",
"prevhash": "70f5701644897c92b60e98dbbfe72e1cfd7a2728c6fa3a29c4b4f6e986b0ccaa",
"coinbaseValue": 5000000974,
"version": 536870912,
"nBits": "207fffff",
"time": 1590152467,
"height": 106,
"num_tx": 4,
"sizeWithoutCoinbase": 1052,
"merkleProof": [
"getInfo": {
"version": 101000300,
"protocolversion": 70015,
"walletversion": 160300,
"balance": 199.99997068,
"blocks": 104,
"timeoffset": 0,
"connections": 4,
"proxy": "",
"difficulty": 4.656542373906925e-10,
"testnet": false,
"stn": false,
"keypoololdest": 1575386196,
"keypoolsize": 1999,
"paytxfee": 0.00000000,
"relayfee": 0.00000250,
"errors": "",
"maxblocksize": 9223372036854775807,
"maxminedblocksize": 128000000,
"maxstackmemoryusagepolicy": 100000000,
"maxstackmemoryusageconsensus": 9223372036854775807
"feeSpec": {
"fees": [
"feeType": "standard",
"miningFee": {
"satoshis": 1,
"bytes": 1
"relayFee": {
"satoshis": 1,
"bytes": 10
"feeType": "data",
"miningFee": {
"satoshis": 2,
"bytes": 1000
"relayFee": {
"satoshis": 1,
"bytes": 10000
3. GET /opreturn/:alias/rotate
alias: Miner ID alias
rotates the Miner ID key for an alias Miner ID
$ curl localhost:9002/opreturn/testMiner/rotate
4. GET /minerid/:alias
alias: Miner ID alias
returns compressed public key (33 byte) hex string for an alias Miner iD
$ curl localhost:9002/minerid/testMiner
5. GET /minerid/:alias/sign/:hash
alias: Miner ID alias hash: SHA256 hash (32 byte hex string) to be fed to ECDSA signing algorithm
returns hash signature (71-73 byte hex string) using an alias Miner ID
$ curl localhost:9002/minerid/testMiner/sign/02644f5000535bbc135f9c8613f86f10c66a4a773eda5e913eff64eb328bc632