eth_getBlockByNumber
Returns information about a block by block number on Polygon PoS.
When to Use This Method​
eth_getBlockByNumber
is crucial for:
- Block Explorers - Display block information and transactions
- Chain Analytics - Analyze block patterns and metrics
- Transaction Verification - Confirm transaction inclusion
- DApp Synchronization - Process blocks sequentially
Parameters​
-
Block Parameter -
QUANTITY|TAG
"latest"
- Most recent mined block"earliest"
- Genesis block"pending"
- Pending block"safe"
- Latest safe block"finalized"
- Latest finalized block- Hex string block number (e.g.,
"0x5BAD55"
)
-
Transaction Details -
Boolean
true
- Returns full transaction objectsfalse
- Returns only transaction hashes
{
"jsonrpc": "2.0",
"method": "eth_getBlockByNumber",
"params": [
"0x5BAD55",
true
],
"id": 1
}
Returns​
Block object with the following fields:
Field | Type | Description |
---|---|---|
number | QUANTITY | Block number, null if pending |
hash | DATA , 32 bytes | Block hash, null if pending |
parentHash | DATA , 32 bytes | Parent block hash |
nonce | DATA , 8 bytes | Proof-of-work nonce (always 0 on Polygon) |
sha3Uncles | DATA , 32 bytes | SHA3 of uncles (always empty on Polygon) |
logsBloom | DATA , 256 bytes | Bloom filter for logs |
transactionsRoot | DATA , 32 bytes | Root of transaction trie |
stateRoot | DATA , 32 bytes | Root of final state trie |
receiptsRoot | DATA , 32 bytes | Root of receipts trie |
miner | DATA , 20 bytes | Beneficiary address (sequencer on Polygon) |
difficulty | QUANTITY | Difficulty (always 0 on Polygon) |
totalDifficulty | QUANTITY | Total difficulty |
extraData | DATA | Extra data field |
size | QUANTITY | Block size in bytes |
gasLimit | QUANTITY | Maximum gas allowed |
gasUsed | QUANTITY | Total gas used by transactions |
timestamp | QUANTITY | Unix timestamp |
transactions | Array | Transaction objects or hashes |
uncles | Array | Uncle hashes (always empty on Polygon) |
baseFeePerGas | QUANTITY | Base fee per gas (EIP-1559) |
l1BlockNumber | QUANTITY | Corresponding L1 block (Base specific) |
Implementation Examples​
- cURL
- JavaScript
- Python
- Go
# Get block with transaction hashes only
curl -X POST https://api-polygon-mainnet-full.n.dwellir.com/YOUR_API_KEY \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "eth_getBlockByNumber",
"params": ["latest", false],
"id": 1
}'
# Get block with full transaction details
curl -X POST https://api-polygon-mainnet-full.n.dwellir.com/YOUR_API_KEY \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "eth_getBlockByNumber",
"params": ["0x5BAD55", true],
"id": 1
}'
import { JsonRpcProvider } from 'ethers';
const provider = new JsonRpcProvider('https://api-polygon-mainnet-full.n.dwellir.com/YOUR_API_KEY');
// Get latest block with transactions
async function getLatestBlock() {
const block = await provider.getBlock('latest', true);
console.log('Block Number:', block.number);
console.log('Block Hash:', block.hash);
console.log('Timestamp:', new Date(block.timestamp * 1000));
console.log('Transactions:', block.transactions.length);
console.log('Gas Used:', block.gasUsed.toString());
console.log('Base Fee:', block.baseFeePerGas?.toString());
return block;
}
// Get block range
async function getBlockRange(start, end) {
const blocks = [];
for (let i = start; i <= end; i++) {
const block = await provider.getBlock(i);
blocks.push({
number: block.number,
timestamp: block.timestamp,
transactions: block.transactions.length,
gasUsed: block.gasUsed.toString()
});
}
return blocks;
}
// Analyze block statistics
async function analyzeBlock(blockNumber) {
const block = await provider.getBlock(blockNumber, true);
const analysis = {
number: block.number,
timestamp: new Date(block.timestamp * 1000),
transactionCount: block.transactions.length,
gasUsed: block.gasUsed,
gasLimit: block.gasLimit,
utilization: (Number(block.gasUsed) / Number(block.gasLimit) * 100).toFixed(2) + '%',
baseFee: block.baseFeePerGas,
totalValue: block.transactions.reduce((sum, tx) => sum + BigInt(tx.value || 0), 0n)
};
return analysis;
}
from web3 import Web3
from datetime import datetime
w3 = Web3(Web3.HTTPProvider('https://api-polygon-mainnet-full.n.dwellir.com/YOUR_API_KEY'))
def get_block_details(block_identifier='latest', full_transactions=False):
"""Get block with optional full transaction details"""
block = w3.eth.get_block(block_identifier, full_transactions)
return {
'number': block['number'],
'hash': block['hash'].hex(),
'timestamp': datetime.fromtimestamp(block['timestamp']),
'transactions': len(block['transactions']),
'gas_used': block['gasUsed'],
'gas_limit': block['gasLimit'],
'base_fee': block.get('baseFeePerGas', 0)
}
def analyze_blocks(start_block, num_blocks=10):
"""Analyze multiple blocks for patterns"""
blocks_data = []
for i in range(num_blocks):
block_num = start_block + i
block = w3.eth.get_block(block_num)
blocks_data.append({
'number': block_num,
'timestamp': block['timestamp'],
'tx_count': len(block['transactions']),
'gas_used': block['gasUsed'],
'block_time': block['timestamp'] - blocks_data[-1]['timestamp']
if blocks_data else 0
})
# Calculate averages
avg_tx = sum(b['tx_count'] for b in blocks_data) / len(blocks_data)
avg_gas = sum(b['gas_used'] for b in blocks_data) / len(blocks_data)
avg_time = sum(b['block_time'] for b in blocks_data[1:]) / (len(blocks_data) - 1)
return {
'blocks': blocks_data,
'averages': {
'transactions_per_block': avg_tx,
'gas_per_block': avg_gas,
'block_time': avg_time
}
}
package main
import (
"context"
"fmt"
"log"
"math/big"
"time"
"github.com/ethereum/go-ethereum/ethclient"
)
func main() {
client, err := ethclient.Dial("https://api-polygon-mainnet-full.n.dwellir.com/YOUR_API_KEY")
if err != nil {
log.Fatal(err)
}
// Get latest block
block, err := client.BlockByNumber(context.Background(), nil)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Block Number: %s\n", block.Number().String())
fmt.Printf("Block Hash: %s\n", block.Hash().Hex())
fmt.Printf("Block Time: %s\n", time.Unix(int64(block.Time()), 0))
fmt.Printf("Transactions: %d\n", len(block.Transactions()))
fmt.Printf("Gas Used: %d\n", block.GasUsed())
// Get specific block
blockNumber := big.NewInt(1000000)
historicalBlock, err := client.BlockByNumber(context.Background(), blockNumber)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Historical Block: %s\n", historicalBlock.Number().String())
}
Response Example​
Block with Transaction Hashes​
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"baseFeePerGas": "0x3e",
"difficulty": "0x0",
"extraData": "0x",
"gasLimit": "0x1c9c380",
"gasUsed": "0x4f916",
"hash": "0x1234567890abcdef...",
"logsBloom": "0x00000000...",
"miner": "0x4200000000000000000000000000000000000011",
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"nonce": "0x0000000000000000",
"number": "0x5bad55",
"parentHash": "0xabcdef1234567890...",
"receiptsRoot": "0x...",
"sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"size": "0x4d6",
"stateRoot": "0x...",
"timestamp": "0x64f1b438",
"totalDifficulty": "0x0",
"transactions": [
"0xhash1...",
"0xhash2...",
"0xhash3..."
],
"transactionsRoot": "0x...",
"uncles": []
}
}
Common Use Cases​
1. Block Explorer Display​
async function formatBlockForExplorer(blockNumber) {
const block = await provider.getBlock(blockNumber, true);
return {
number: block.number,
hash: block.hash,
timestamp: new Date(block.timestamp * 1000).toISOString(),
miner: block.miner,
transactionCount: block.transactions.length,
gasUsed: `${(Number(block.gasUsed) / 1e6).toFixed(2)}M`,
gasLimit: `${(Number(block.gasLimit) / 1e6).toFixed(2)}M`,
utilization: `${(Number(block.gasUsed) / Number(block.gasLimit) * 100).toFixed(2)}%`,
baseFee: `${Number(block.baseFeePerGas) / 1e9} Gwei`,
burnt: formatEther(block.gasUsed * block.baseFeePerGas)
};
}
2. Transaction Confirmation​
async function confirmTransaction(txHash, confirmations = 6) {
const tx = await provider.getTransaction(txHash);
if (!tx) throw new Error('Transaction not found');
const receipt = await provider.getTransactionReceipt(txHash);
if (!receipt) {
console.log('Transaction pending...');
return false;
}
const currentBlock = await provider.getBlockNumber();
const confirmCount = currentBlock - receipt.blockNumber + 1;
if (confirmCount >= confirmations) {
const block = await provider.getBlock(receipt.blockNumber, true);
const txInBlock = block.transactions.find(t => t.hash === txHash);
return {
confirmed: true,
confirmations: confirmCount,
block: receipt.blockNumber,
timestamp: block.timestamp,
position: txInBlock ? block.transactions.indexOf(txInBlock) : -1
};
}
return {
confirmed: false,
confirmations: confirmCount,
needed: confirmations - confirmCount
};
}
3. Block Time Analysis​
async function analyzeBlockTimes(count = 100) {
const latest = await provider.getBlockNumber();
const blocks = [];
for (let i = 0; i < count; i++) {
const block = await provider.getBlock(latest - i);
blocks.push({
number: block.number,
timestamp: block.timestamp
});
}
const blockTimes = [];
for (let i = 1; i < blocks.length; i++) {
blockTimes.push(blocks[i-1].timestamp - blocks[i].timestamp);
}
return {
average: blockTimes.reduce((a, b) => a + b, 0) / blockTimes.length,
min: Math.min(...blockTimes),
max: Math.max(...blockTimes),
blocks: blockTimes
};
}
4. Gas Price Tracking​
async function trackGasPrices(blocks = 10) {
const latest = await provider.getBlockNumber();
const gasPrices = [];
for (let i = 0; i < blocks; i++) {
const block = await provider.getBlock(latest - i, true);
// Calculate effective gas prices from transactions
const prices = block.transactions
.filter(tx => tx.gasPrice || tx.maxFeePerGas)
.map(tx => {
if (tx.type === 2) { // EIP-1559
return BigInt(tx.maxFeePerGas) < BigInt(block.baseFeePerGas) + BigInt(tx.maxPriorityFeePerGas)
? BigInt(tx.maxFeePerGas)
: BigInt(block.baseFeePerGas) + BigInt(tx.maxPriorityFeePerGas);
}
return BigInt(tx.gasPrice);
});
if (prices.length > 0) {
const avgPrice = prices.reduce((a, b) => a + b, 0n) / BigInt(prices.length);
gasPrices.push({
block: block.number,
baseFee: Number(block.baseFeePerGas) / 1e9,
avgPrice: Number(avgPrice) / 1e9,
txCount: block.transactions.length
});
}
}
return gasPrices;
}
Performance Optimization​
Parallel Block Fetching​
async function getBlocksParallel(startBlock, count) {
const promises = [];
for (let i = 0; i < count; i++) {
promises.push(provider.getBlock(startBlock + i));
}
const blocks = await Promise.all(promises);
return blocks;
}
Block Caching​
class BlockCache {
constructor(maxSize = 100) {
this.cache = new Map();
this.maxSize = maxSize;
}
async getBlock(provider, blockNumber, fullTx = false) {
const key = `${blockNumber}-${fullTx}`;
if (this.cache.has(key)) {
return this.cache.get(key);
}
const block = await provider.getBlock(blockNumber, fullTx);
// LRU eviction
if (this.cache.size >= this.maxSize) {
const firstKey = this.cache.keys().next().value;
this.cache.delete(firstKey);
}
this.cache.set(key, block);
return block;
}
}
Error Handling​
Error Code | Description | Solution |
---|---|---|
-32602 | Invalid block number | Check block exists and format |
-32000 | Block not found | Block may not be mined yet |
-32005 | Rate limit exceeded | Implement backoff strategy |
async function safeGetBlock(blockNumber, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
const block = await provider.getBlock(blockNumber);
if (!block) {
throw new Error(`Block ${blockNumber} not found`);
}
return block;
} catch (error) {
if (i === maxRetries - 1) throw error;
// Exponential backoff for rate limits
if (error.code === -32005) {
await new Promise(r => setTimeout(r, Math.pow(2, i) * 1000));
}
}
}
}
Need help? Contact our support team or check the Polygon documentation.