BNB Smart Chain

BNB Smart Chain

Working with Blocks

A swap on PancakeSwap, a lending position on Venus, a plain BNB transfer: none of it is real until it lands inside a sealed block on chainId 56. Every meaningful interaction with BNB Smart Chain resolves to a block in the end. BSC seals a fresh one roughly every three seconds under its PoSA validator schedule. Any responsive dApp, indexer, or backend service rests on reading and reacting to those blocks correctly. Work through this guide and you can fetch the latest height, pull individual blocks by number (with or without full transaction bodies), watch new headers arrive, and judge how many confirmations a transaction needs before you treat it as final against the bsc.therpc.io endpoint.

Core Concepts

  • Block structure. A BSC block carries a number, a hash plus parentHash linking it to its predecessor, the sealing validator in miner, the timestamp, the gasLimit and gasUsed pair, a baseFeePerGas field, and the transactions list. It also carries a uncles array that is always empty under PoSA.
  • Retrieval at the JSON-RPC level. eth_blockNumber returns the current head. eth_getBlockByNumber (or eth_getBlockByHash) returns the full block; pass the boolean true flag to inline every transaction object rather than just its hash.
  • Monitoring. Watching the chain means one of two things: subscribing to newBlockHeaders over WebSocket, or polling eth_blockNumber on a short interval. You need it whenever you index events, fire jobs on each new block, or keep a live UI current.
  • Confirmations and finality. Each block built on top of the one holding your transaction adds a confirmation. The deeper it sits, the harder it is to displace.
  • Finality on BSC. PoSA fast finality makes a BSC block practically irreversible within a handful of slots, so you wait for far fewer confirmations than Ethereum's probabilistic settlement demands.

Block Retrieval

// Get latest block number
const blockNumber = await web3.eth.getBlockNumber();
// Get block by number
const block = await web3.eth.getBlock(blockNumber);
// Get block with full transaction details
const blockWithTx = await web3.eth.getBlock(blockNumber, true);

Best Practices

  • Delays and timeouts. Wrap each RPC call in a bounded timeout and retry transient failures with exponential backoff, so a slow round trip to bsc.therpc.io never stalls the whole pipeline.
  • Error handling. A null block response means "not yet available," not an error. Tell it apart from rate-limit or transport failures, and raise a clear error when a requested height sits beyond the current head.
  • Account for reorgs. Recent blocks can still shift even with PoSA fast finality, so hold off on irreversible actions until a transaction sits a few confirmations deep on chainId 56.
  • Caching. Blocks older than your finality threshold never change. Cache their hash, timestamp, and transaction set aggressively, but never cache the unconfirmed head.
  • Gas and block space. Track gasUsed against gasLimit alongside the prevailing baseFeePerGas, so you can pick fees that clear quickly when BSC blocks fill up during PancakeSwap or Venus activity spikes.

See also

Ready to call this in production?

Free tier covers personal projects. Pay-as-you-go scales without a card.