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.
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).
You can install nodejs and npm easily with apt install, just run the following commands.
```console $ sudo apt install nodejs $ sudo apt install npm ```
You can find more information about the installation on the official Node.js website and the official NPM website.
$ git clone https://github.com/bitcoin-sv/minerid-reference.git $ cd minerid-reference $ npm install
Create a config.json and edit it with your settings:
port
minerIdDataPath
which stores user's miner IDskeystore
which stores miner ID private keysnetwork
(mainnet="livenet" | testnet="testnet" | regtest="regtest")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" services: minerid: image: bitcoinsv/minerid:1.1.1 ports: - 9002:9002 restart: always environment: NODE_CONFIG: '{ "bitcoin": { "rpcHost":"host.docker.internal" }, "network": "regtest" }' volumes: - minerid:/root/.keystore - minerid:/root/.minerid-client volumes: minerid: 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 aliasblockHeight
: 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
body:
{ "blockHeight": number, "alias": string, "coinbase2": string, "jobData": { "miningCandidate": {}, "getInfo": {}, "feeSpec": {} } }
returns updated coinbase2 with the Miner ID output included
Field | Function |
---|---|
blockHeight | Height of the block which the coinbase transaction will be in |
alias | Alias of the Miner ID |
coinbase2 | Second part of the coinbase (coinb2 ) as shown in the stratum protocol |
jobData | Data specific to a mining job to be added to the Miner ID coinbase document throught the extensions |
miningCandidate | BitCoin RPC getminingcandidate response |
getInfo | BitCoin RPC getinfo response |
feeSpec | mAPI default fees |
Note: The coinbase transaction is split up in the stratum protocol as follows:
{ "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": [ "9bd12ce6508574b3163aadb14eab7bd862306da85b221eb284fb41d6012db98f", "56f04cc78ac493defced65dd58f4437c67bcc697b59778b0cd96c3c64c1b0bbf" ] }, "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 OK
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 02644f5000535bbc135f9c8613f86f10c66a4a773eda5e913eff64eb328bc6326a
5. GET /minerid/:alias/sign/:hash
alias
: Miner ID aliashash
: 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 3045022100e0f86a5b1748ae48b0d10ea305202769d754071272cba0fbb82f74f8e8da8b530220494351742f3ba9e51b155df15b13f27c927d21956822aedcbb7d179c66d4d4c0