Docs

eth_getBlockByHash - Ink RPC Method

Retrieve complete block data by block hash on Ink. Essential for Ink developers, DeFi builders, and teams deploying Solidity applications on the Superchain building on Kraken's DeFi-focused Ethereum L2 built on the OP Stack and connected to the Optimism Superchain.

Returns information about a block by hash on Ink.

Why Ink? Build on Kraken's DeFi-focused Ethereum L2 built on the OP Stack and connected to the Optimism Superchain with 1s block times, ETH gas, Kraken-backed infrastructure, OP Stack compatibility, and Superchain interoperability.

When to Use This Method

eth_getBlockByHash is essential for Ink developers, DeFi builders, and teams deploying Solidity applications on the Superchain:

  • Block verification using deterministic hash lookup: Retrieve block data by its unique, immutable hash on Ink
  • Chain reorganization handling: Track blocks reliably by hash during reorgs on Kraken's DeFi-focused Ethereum L2 built on the OP Stack and connected to the Optimism Superchain
  • Cross-chain bridge finality verification: Confirm block existence by its canonical hash for low-fee DeFi applications, cross-chain liquidity, and EVM-compatible smart contracts
  • Deterministic queries when block number may change: Ensure consistent results for applications that need stable references regardless of chain state

Common Use Cases

1. Verify a Specific Block from a Transaction's blockHash Field

When a transaction response includes blockHash, use eth_getBlockByHash to retrieve the full parent block. This cross-references the transaction's context and confirms which block it was included in on Ink.

JavaScript
import { JsonRpcProvider } from 'ethers';

const provider = new JsonRpcProvider('https://api-ink-mainnet.n.dwellir.com/YOUR_API_KEY');

async function verifyBlockFromTx(txHash) {
  const tx = await provider.getTransaction(txHash);
  if (!tx || !tx.blockHash) return null;

  const block = await provider.getBlock(tx.blockHash);
  console.log(`Transaction ${txHash} in block #${block.number}`);
  console.log(`Block hash: ${block.hash}`);
  console.log(`Block timestamp: ${new Date(block.timestamp * 1000).toISOString()}`);
  return block;
}

verifyBlockFromTx('0x17d1ffb71c72ff3a382b13a1ced2218313e334b36a6c8f5917b743e4b4436a9b');

2. Cross-Reference Blocks During Chain Reorganization

During a chain reorganization, block numbers can shift but block hashes remain unique identifiers. Use eth_getBlockByHash to verify the canonical chain state and detect whether a previously observed block has been orphaned on Kraken's DeFi-focused Ethereum L2 built on the OP Stack and connected to the Optimism Superchain.

Python
from web3 import Web3

w3 = Web3(Web3.HTTPProvider('https://api-ink-mainnet.n.dwellir.com/YOUR_API_KEY'))

def verify_block_still_canonical(block_hash):
    block = w3.eth.get_block(block_hash)
    if block is None:
        print(f'Block {block_hash} has been pruned or orphaned')
        return False
    print(f'Block {block_hash} still canonical at height #{block.number}')
    return True

# Check a known block hash
verify_block_still_canonical('0x4da3692d55759ca2fa35e8093aaedf76b1075e5c2d6346365e318c153f0327db')

3. Audit Block Data by Known Hash Reference

For compliance and audit workflows, store block hashes as permanent references. Re-querying eth_getBlockByHash with a stored hash guarantees you retrieve the exact same block data, even months later on Ink.

Go
package main

import (
    "context"
    "fmt"
    "log"

    "github.com/ethereum/go-ethereum/common"
    "github.com/ethereum/go-ethereum/ethclient"
)

func main() {
    client, _ := ethclient.Dial("https://api-ink-mainnet.n.dwellir.com/YOUR_API_KEY")

    knownHash := common.HexToHash("0x4da3692d55759ca2fa35e8093aaedf76b1075e5c2d6346365e318c153f0327db")
    block, err := client.BlockByHash(context.Background(), knownHash)
    if err != nil || block == nil {
        log.Fatal("Block not found: may be pruned from node")
    }

    fmt.Printf("Audited block #%d\n", block.Number().Uint64())
    fmt.Printf("Hash: %s\n", block.Hash().Hex())
    fmt.Printf("Transactions: %d\n", len(block.Transactions()))
}

Best Practices

  • Hash-based lookups are more reliable during chain reorgs than number-based: A block hash uniquely identifies one canonical block, while a block number may shift to a different block after a reorg
  • Store block hashes in your database for future verification: Persisting the hash alongside related records enables deterministic re-querying for audits and data integrity checks
  • Handle null results gracefully: Blocks can be pruned by the node, especially on non-archive endpoints; your application should treat a null response as a missing or unavailable block
  • For L2 optimistic rollups, verify the L1 anchor hash separately: The hash on the L2 chain references a different block space than the L1 anchor; validate both independently for full finality confidence

Code Examples

Error Handling

Error CodeMessageDescription
-32602Invalid paramsInvalid block hash format
-32000Block not foundBlock with this hash does not exist