I understand that mining a block involves trying to generate a hash that is less than or equal to a target dictated by a required difficulty. Ethereum Wiki on Ethash:

def mine(full_size, dataset, header, difficulty):
    # zero-pad target to compare with hash on the same digit
    target = zpad(encode_int(2**256 // difficulty), 64)[::-1]
    from random import randint
    nonce = randint(0, 2**64)
    while hashimoto_full(full_size, dataset, header, nonce) > target:
        nonce = (nonce + 1) % 2**64
    return nonce

I also learned from this SE topic that the block hash itself isn't checked against the target, but rather it's Ethash(hash(block header), nonce) < TARGET, which explains why Ethereum blocks don't have the leading zeros we're accustomed to with Bitcoin.

To calculate the difficulty, we'd presumably invert the operation that generated a target from difficulty to instead generate a difficulty from an Ethash? And is a block's difficulty that inversion applied to Ethash(hash(block header), nonce) or is it that inversion applied to the target to generate the original required difficulty?

If the former, shouldn't we be able to regain consensus immediately in forks without requiring additional blocks given that the consensus chain is that with highest total cumulative difficulty, and the probability that multiple prongs would share this would be effectively zero?

If the latter, and given this excellent explanation for how the difficulty adjustment algorithm works, and given that the difficulty bomb continues to be postponed, I'd expect consecutive blocks on Etherscan to share difficulty with some regularity, i.e. in cases when the block is mined within 10-20 seconds of its parent. But this is contrary to what I see glancing at recent blocks on Etherscan.

Returning to the central question: How can I calculate a given Ethereum block's difficulty?

2 Answers 2


The current algorithm for adjusting difficulty can be found in EIP-100, the Yellow Paper (Page 7, Equation 45), or implemented in geth here. The algorithm for adjusting required difficulty is also used to define a block's difficulty. That's to say that a block's difficulty is defined by its parent's difficulty as well as the difference in timestamps between it and its parent, as well as whether its parent has uncles. Critically, though, it is independent of the ethash output. For this reason, two blocks with the same parent may share the same difficulty if they have similar timestamps: they need to either both have been mined within 9 seconds of their shared parent or both have been mined between 9 and 18 (excluding the endpoint) of their mutual parent. Post EIP-100 implementation in Byzantium, uncles do matter for total difficulty.

I also suggested above that I would have expected a block to have the same difficulty as its parent if and only if it was mined between 9 and 18 second of its parent. I was mistaken. Even if this is the case, a block will have higher difficulty than its parent with the difference coming from the epsilon term in the Yellow Paper, equation 50. Even though this term changes infrequently, every 100,000 blocks, a block's difficulty is still increased by this amount relative to its parent. So while you will generally find blocks' difficulties to be distinct from other blocks, you may find that the difference in difficulty between block n+1 and block n equals the difference between block n and block n-1 if block n+1 was mined between 9 and 18 seconds after block n, assuming no difference is inserted by uncle inclusion.


You can call JSON-RPC using ethers and a provider. The result of eth_getBlockByNumber contains a field called difficulty.

The JS would look roughly like this:

import ethers;

async () => {
    const provider = new ethers.providers.JsonRpcProvider(<YOUR JSONRPC URL>);
    const block = await provider.getBlock(100004);
    const difficulty = block.difficulty;

Read more about it here: https://playground.open-rpc.org/?schemaUrl=https://raw.githubusercontent.com/ethereum/eth1.0-apis/assembled-spec/openrpc.json&uiSchema%5BappBar%5D%5Bui:splitView%5D=false&uiSchema%5BappBar%5D%5Bui:input%5D=false&uiSchema%5BappBar%5D%5Bui:examplesDropdown%5D=false

  • Thank you, @Origami, as that is helpful, but it doesn't really answer my question as to how that block.difficulty number is calculated.
    – Shane
    Mar 9, 2022 at 14:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.