sf.ethereum.type.v2.Block
Block is the representation of the tracing of a block in the Ethereum blockchain. A block is a collection of TransactionTrace that are grouped together and processed as an atomic unit. Each TransactionTrace is composed of a series of Call (a.k.a internal transactions) and there is also at least one call per transaction a.k.a the root call which essentially has the same parameters as the transaction itself (e.g. from, to, gas, value, etc.).
The exact tracing method used to build the block must be checked against [DetailLevel] field. There is two levels of details available, BASE and EXTENDED. The BASE level has been extracted using archive node RPC calls and will contain only the block header, transaction receipts and event logs. Refers to the Firehose service provider to know which blocks are offered on each network.
The EXTENDED level has been extracted using the Firehose tracer and all fields are available in this Protobuf.
The Ethereum block model is used across many chains which means that it happen that certain fields are not available in one chain but are available in another. Each field should be documented when necesssary if it's available on a subset of chains.
One major concept to get about the Block is the concept of 'ordinal'. The ordinal is a number that is used to globally order every element of execution that happened throughout the processing of the block like [TransactionTracer], Call, Log, BalanceChange, [StateChange], etc. Element that have a start and end interval, [Transaction] and Call, will have two ordinals: begin_ordinal and end_ordinal. Element that are executed as "point in time" Log, BalanceChange, [StateChange], etc. will have only one ordinal named ordinal. If you take all of the message in the Block that have an 'ordinal' field in an array and you sort each element against the ordinal field, you will get the exact order of execution of each element in the block.
All the 'ordinal' fields in a block are globally unique for the given block, it is not a chain-wide global ordering. Furthermore, caution must be take with reverted elements due to execution failure. For anything attached to a Call that has a state_reverted field set to true, the ordinal field is not reliable and should not be used to order the element against other elements in the block as those element might have 0 as the ordinal. Only successful calls have a reliable ordinal field.
Failed Transaction State Changes
An important edge case to understand when processing Firehose blocks is that certain state changes persist even when a transaction fails. This behavior follows Ethereum's execution model where some operations are irreversible once they occur, regardless of transaction outcome.
The following state changes are typically preserved even for failed transactions:
- Gas consumption (BalanceChange.REASON_GAS_BUY, GasChange.REASON_INTRINSIC_GAS): Gas is always consumed
when a transaction is processed, even if execution fails
- Gas refunds (BalanceChange.REASON_GAS_REFUND): Gas refunds are processed regardless of transaction outcome
- Nonce increments: The sender's nonce is incremented to prevent replay attacks
- Transaction fees (BalanceChange.REASON_REWARD_TRANSACTION_FEE): Miners receive fees regardless
of transaction success to compensate for computational work
However, value transfers, contract state changes, and other application-level modifications are reverted on transaction failure. When processing failed transactions, applications should filter state changes appropriately based on their specific requirements and the transaction's success status.
SetCode Transaction Handling (EIP-7702)
SetCode transactions (TRX_TYPE_SET_CODE) require special handling for nonce and code changes. According to EIP-7702, nonce changes and code changes for each accepted authorization in the transaction should be recorded in the state even if the transaction fails. When processing SetCode transactions, both NonceChange and CodeChange entries will be present for each authorized account, with the transaction sender's nonce change appearing first without a corresponding code change. Applications must handle these state changes appropriately, preserving them regardless of transaction success status to maintain EIP-7702 compliance.
Ver represents that data model version of the block, it is used internally by Firehose on Ethereum as a validation that we are reading the correct version.
Hash is the block's hash.
Number is the block's height at which this block was mined.
Size is the size in bytes of the RLP encoding of the block according to Ethereum rules.
Header contain's the block's header information like its parent hash, the merkel root hash and all other information the form a block.
Uncles represents block produced with a valid solution but were not actually chosen as the canonical block for the given height so they are mostly "forked" blocks.
If the Block has been produced using the Proof of Stake consensus algorithm, this field will actually be always empty.
TransactionTraces hold the execute trace of all the transactions that were executed in this block. In in there that you will find most of the Ethereum data model.
They are ordered by the order of execution of the transaction in the block.
BalanceChanges here is the array of ETH transfer that happened at the block level outside of the normal transaction flow of a block. The best example of this is mining reward for the block mined, the transfer of ETH to the miner happens outside the normal transaction flow of the chain and is recorded as a BalanceChange here since we cannot attached it to any transaction.
Only available in DetailLevel: EXTENDED
DetailLevel affects the data available in this block.
DetailLevel_EXTENDED
Describes the most complete block, with traces, balance changes, storage changes. It is extracted during the execution of the block.
DetailLevel_BASE
Describes a block that contains only the block header, transaction receipts and event logs: everything that can be extracted using the base JSON-RPC interface (https://ethereum.org/en/developers/docs/apis/json-rpc/#json-rpc-methods) Furthermore, the eth_getTransactionReceipt call has been avoided because it brings only minimal improvements at the cost of requiring an archive node or a full node with complete transaction index.
CodeChanges here is the array of smart code change that happened that happened at the block level outside of the normal transaction flow of a block. Some Ethereum's fork like BSC and Polygon has some capabilities to upgrade internal smart contracts used usually to track the validator list.
On hard fork, some procedure runs to upgrade the smart contract code to a new version. In those network, a CodeChange for each modified smart contract on upgrade would be present here. Note that this happen rarely, so the vast majority of block will have an empty list here.
Only available in DetailLevel: EXTENDED
System calls are introduced in Cancun, along with blobs. They are executed outside of transactions but affect the state.
Only available in DetailLevel: EXTENDED
Withdrawals represents the list of validator balance withdrawals processed in this block. Introduced in the Shanghai hard fork (EIP-4895).
This field has been added because Geth blocks include withdrawals after Shanghai fork, but our previous Firehose model didn't capture this data. Currently experimental - NOT ready for production use yet as we validate the tracing implementation.
Only available when Shanghai fork is active on the chain.