Developer Fundamentals

-- I. Read Blocks

Learn how to retrieve and interpret block data on VeChainThor using compressed and expanded methods to support real-time blockchain interactions in your app.

Understanding Blocks on VeChainThor

Now that you understand VeChainThor fundamentals and how to connect, it's time to explore how to retrieve and interpret onchain data. This chapter focuses on accessing blocks, transactions, accounts, and contract states to power your applications with real-time blockchain insights.

A block is a change to the blockchain storage with a batch of changes that happen simultaneously. With VeChain, a new block is generated approximately every 10 seconds, even if no transactions have been published.

The most relevant information for interacting with blocks includes:

  • number: the number of the block

  • id: a unique ID representing the block

  • parentID: the previous block that the block is based on

  • timestamp: the Unix time at which the block was stored

  • isFinalized: is the block securely finalized in a snapshot

  • transactions: contains either all transaction IDs or full transaction details, including receipts

A block can be requested by its number, ID, or, additionally, the reserved words "best" and "finalized" reference the latest or epoch-ending blocks.

// get the block and transaction ids within it
const compressed = await thor.blocks.getBlockCompressed(12345678);
console.log(compressed);

// get the block and transaction data including receipts
const expanded = await thor.blocks.getBlockExpanded(12345678);
console.log(expanded);

Test It Yourself

The snippet below shows how you can make a request to the blockchain and receive a compressed and expanded response (you'll learn more about the response types later in this lesson):

import { ThorClient } from '@vechain/sdk-network';
const thor = ThorClient.at('https://mainnet.vechain.org');

const blockIdOrNumber = process.argv[2] ?? 12345678;
console.log('Reading block', blockIdOrNumber);

// get the block and transaction ids within it
const compressed = await thor.blocks.getBlockCompressed(blockIdOrNumber);
console.log(compressed);

// get the block and transaction data including receipts
const expanded = await thor.blocks.getBlockExpanded(blockIdOrNumber);
console.log(expanded);

There are two methods to obtain block details:

  1. The compressed version includes all data and only the transaction IDs.

  2. The expanded version also encompasses full transaction details along with the generated outputs.

The JSON-API formats below represent both types of responses:

Compressed response – Provides a minimal set of block details.

{
  "number": 12345678,
  "id": "0x00bc614e285d68f8819b6dfdd729dad6fafbed9d2fdd65b57e4001a47d7f280c",
  "size": 944,
  "parentID": "0x00bc614dda10f9e1dffb147280c7f50040062e29fb2f43f5d81a0e8b80d446c3",
  "timestamp": 1653978240,
  "gasLimit": 20512434,
  "beneficiary": "0x352f2753c668d9c970fc0f7bf54c0fce628b97a4",
  "gasUsed": 109874,
  "totalScore": 1197718067,
  "txsRoot": "0x49b2810ae87142e7cdc2c57c28c5b6504da99a65e8d64f58d901c41f375be647",
  "txsFeatures": 1,
  "stateRoot": "0xd3d5f42fde4a4981675478153a29fa51ad513e7ba929a4645118f94711542f35",
  "receiptsRoot": "0xc20a328a65a01eff549523b0f1b2e7227c91015bc414894d060d0beac544df6a",
  "com": false,
  "signer": "0x68fff2dc8217d5f722a5a2df9400cde367c9366e",
  "isTrunk": true,
  "isFinalized": true,
  "transactions": [
    "0x2196cc6ca9c8dbb0ff4d6c5538499d381ac5bfbb62e067d862a53ef5466d282c",
    "0x853ebeca324fea48e5536111bea7889f9d0e92fe2cbba893ecd1671e1247f01c",
    "0xfc99fe103fccbe61b3c042c1da3499b883d1b17fb40160ed1170ad5e63751e07"
  ]
}

The expanded response also returns the full details of each transaction in the block.

There are specific keywords associated with special blocks:

  • Genesis – refers to the initial block (number 0) on a chain, serving to identify the available chain on a network.

  • Best – represents the most recent block, typically having a maximum age of 10 seconds, as a new block is added every 10 seconds.

  • Final – denotes the most recent finalized block, marking the end of an epoch. It is guaranteed that there will be no further re-ordering or changes. A checkpoint happens every 180 blocks, and the finalization of a checkpointed block occurs again after 180 blocks.