How Rootstock Calculates Secured Hashrate
Rootstock is secured by Bitcoin miners who merge mine both chains with the same proof of work. The share of Bitcoin's hash power that does this is measurable. Every participating miner leaves a tag inside the Bitcoin block they mine, so you can count the tagged blocks and scale Bitcoin's total hashrate by that share.
The Rootstock Explorer publishes the result. This page explains each step of the calculation, so anyone can independently verify the published numbers or re-derive them from raw chain data. One framing matters before the math: the metric measures participation, not security directly. It says how much hash power takes part in merge mining, not what attacking Rootstock would cost.
The published metrics
The Explorer API serves the metrics at GET /api/v3/stats. It exposes four hashrate related fields.
| Field | Meaning | Unit |
|---|---|---|
hashrate | Rootstock network hashrate, reported by a Rootstock node | hashes per second, as a string |
bitcoinHashrate | Estimated total Bitcoin network hashrate | hashes per second, as a string |
mergeMiningPercentage | Share of recent Bitcoin blocks that carry the Rootstock merge-mining tag | ratio between 0 and 1, as a string |
rootstockSecuredHashrate | Bitcoin hash power actively securing Rootstock | hashes per second, as a string |
A response looks like this.
{
"data": {
"activeAccounts": 112242,
"hashrate": "608900501771594900000",
"bitcoinHashrate": "909038172416238900000",
"rootstockSecuredHashrate": "565421743242900595800",
"mergeMiningPercentage": "0.622000",
"circulatingSupply": "1662.234700019254340177",
"totalSupply": 21000000
}
}
The two hashrate values are strings because a network hashrate is a 21-digit number, far past the range where a JSON number stays exact. mergeMiningPercentage travels as a string for the same reason, carrying six fixed decimals. The hashrates parse cleanly with JavaScript's built-in BigInt or ethers' BigNumber; the percentage carries decimals, so use an arbitrary-precision decimal library such as bignumber.js or decimal.js.
Step 1: Find the merge-mining tag in a Bitcoin coinbase
Every Bitcoin block starts with a coinbase transaction, which mints the block reward and pays the miner. A merge-mining pool writes a commitment to the Rootstock block it secured into that transaction. The commitment starts with the ASCII string RSKBLOCK:, which is 0x52534b424c4f434b3a in hex, followed by 32 bytes holding the Rootstock block's merged-mining hash.
The merged mining implementation guide documents the exact wire format that pools produce. For measurement you only need to answer one question: do those nine tag bytes appear anywhere in the coinbase?

Bitcoin block 955,501 answers yes. Its coinbase carries an OP_RETURN output holding this script.
6a 29 52534b424c4f434b3a 410ac1c4b7fb2330ffa2b6434afb44429b702189371c4158d102fe13008922b6
Each piece has a job.
6ais theOP_RETURNopcode, which marks the output as data rather than spendable value.29pushes the next 41 bytes.52534b424c4f434b3ais theRSKBLOCK:tag.- The final 32 bytes are the merged-mining hash of the Rootstock block that this Bitcoin block secured.
Nine tag bytes plus 32 hash bytes make 41, which matches the push opcode. The block is merge mined, and it records a commitment to a specific Rootstock block.
Those 32 bytes are a Rootstock block header hash computed for merged mining, not the block's canonical hash, and eth_getBlockByHash looks blocks up by their canonical hash only. Passing the merged-mining value returns null. The field travels in the other direction: request a block by number or canonical hash and read hashForMergedMining from the response, as the reproduction section below does. Rootstock nodes use it during consensus to verify that the proof of work in this Bitcoin block belongs to that Rootstock block.
Two properties of this check matter for correctness. First, classification depends on tag presence alone. The calculation never looks at Rootstock transactions, so a chain of custody back to Rootstock's own state is not required. Second, the scan covers both places the tag can live. Pools normally use an OP_RETURN output, but the coinbase input script is also valid, and checking only one location undercounts.