NOTE: This standard is used by Namecoin, but new merged mining data should likely propose a new BIP to supercede it with something based on p2pool’s merged mining.
Terminology
- Auxiliary Proof-of-Work (POW)
- a.k.a “AuxPOW”. This is the way that merged mining can exist; it is the relationship between two blockchains for one to trust the other’s work as their own and accept AuxPOW blocks.
- Merged Mining
- The act of using work done on one blockchain on more than one chain, using Auxiliary POW.
- Auxiliary Blockchain
- The altcoin that is accepting work done on alternate chains as valid on its own chain. Client applications have to be modified to accept Auxiliary POW.
- Parent Blockchain
- The blockchain where the actual mining work is taking place. This chain does not need to be aware of the Auxiliary POW logic, as AuxPOW blocks submitted to this chain are still valid blocks.
- Parent Block
- Not to be confused with the “previous block”. This is a block that is structured for the parent blockchain (i.e. the prev_block hash points to the prior block on the parent blockchain). The header of this block is part of the AuxPOW Block in the auxiliary blockchain.
- AuxPOW Block
- This is a new type of block that is similar to a standard blockchain block, with two important differences. Firstly, the hash of the block header does NOT meet the difficulty level of the blockchain (so, if interpreted by a naive client, will be thrown out as not meeting the difficulty level). Secondly, it has additional data elements that show that the miner who created this block actually did mining activity (hashing) on the parent blockchain, and that work meets the difficulty level of the auxiliary blockchain, which is why this block should be accepted.
Aux proof-of-work block
This is used to prove work on the auxiliary blockchain. In vinced’s original implementation it’s generated by calling the getworkaux RPC method on the parent blockchain client (bitcoind) and then the work is then submitted by passing it to the auxiliary chain client (namecoind) as the second parameter to getauxblock.
When receiving an Aux proof-of-work block in a “block” network message, the data received is similar to a standard block, but extra data is inserted between the nonce and txn_count elements. In the below table, the shaded rows are the same as the standard block definition:
Field Size | Description | Data type | Comments |
---|---|---|---|
4 | version | uint32_t | |
32 | prev_block | char[32] | |
32 | merkle_root | char[32] | |
4 | timestamp | uint32_t | |
4 | bits | uint32_t | |
4 | nonce | uint32_t | |
? | coinbase_txn | txn | Coinbase transaction that is in the parent block, linking the AuxPOW block to its parent block |
32 | block_hash | char[32] | Hash of the parent_block header |
? | coinbase_branch | Merkle branch | The merkle branch linking the coinbase_txn to the parent block’s merkle_root |
? | blockchain_branch | Merkle branch | The merkle branch linking this auxiliary blockchain to the others, when used in a merged mining setup with multiple auxiliary chains |
80 | parent_block | Block header | Parent block header |
? | txn_count | var_int | |
? | txns | tx[] |
For the coinbase_branch merkle branch, because the coinbase transaction is the first transaction in the block (if using Bitcoin as a parent chain, i.e. hash #7 in the example given below), the branch_side_mask is always going to be all zeroes, because the branch hashes will always be “on the right” of the working hash.
When only working on one auxiliary blockchain, the blockchain_branch link is not needed, and is nulled-out by being presented as 5 bytes of zeros (interpreted as a one-byte var_int indicating a branch_length of zero, and a 32-bit (4 byte) branch_side_mask of all zeroes).
Note that the block_hash element is not needed as you have the full parent_block header element and can calculate the hash from that. The current Namecoin client doesn’t check this field for validity, and as such some AuxPOW blocks have it little-endian, and some have it big-endian.
Merkle Branch
Say Alice created a Merkle tree, and it’s root element is publicly available. For example:
merkleRoot (0) / / 1 2 / / / / 3 4 5 6 / / / / 7 8 9 10 11 12 13 14
Now she wants to prove to Bob that a given hash (#10) was part of that tree, but Bob doesn’t have the full tree (only the public root; hash #0). Alice can send Bob all the hashes she used to make the tree in the first place (hashes #7-#14, total of 7 extra hashes), so Bob can bu