Chains

Block model

sf.ethereum.type.v2.Call

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.

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.

int32ver = 1

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.

byteshash = 2

Hash is the block's hash.

uint64number = 3

Number is the block's height at which this block was mined.

uint64size = 4

Size is the size in bytes of the RLP encoding of the block according to Ethereum rules.

BlockHeaderheader = 5

Header contain's the block's header information like its parent hash, the merkel root hash and all other information the form a block.

BlockHeader[]uncles = 6

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.

TransactionTrace[]transaction_traces = 10

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.

BalanceChange[]balance_changes = 11

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

Block.DetailLeveldetail_level = 12

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.

CodeChange[]code_changes = 20

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

Call[]system_calls = 21

System calls are introduced in Cancun, along with blobs. They are executed outside of transactions but affect the state.

Only available in DetailLevel: EXTENDED

Withdrawal[]withdrawals = 22

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.

sf.ethereum.type.v2.BlockHeader

bytesparent_hash = 1
bytesuncle_hash = 2

Uncle hash of the block, some reference it as sha3Uncles, but sha3 is badly worded, so we prefer uncle_hash, also referred as ommers` in EIP specification.

If the Block containing this BlockHeader has been produced using the Proof of Stake consensus algorithm, this field will actually be constant and set to 0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347.

bytescoinbase = 3
bytesstate_root = 4
bytestransactions_root = 5
bytesreceipt_root = 6
byteslogs_bloom = 7
BigIntdifficulty = 8

Difficulty is the difficulty of the Proof of Work algorithm that was required to compute a solution.

If the Block containing this BlockHeader has been produced using the Proof of Stake consensus algorithm, this field will actually be constant and set to 0x00.

uint64number = 9
uint64gas_limit = 10
uint64gas_used = 11
bytesextra_data = 13

ExtraData is free-form bytes included in the block by the "miner". While on Yellow paper of Ethereum this value is maxed to 32 bytes, other consensus algorithm like Clique and some other forks are using bigger values to carry special consensus data.

If the Block containing this BlockHeader has been produced using the Proof of Stake consensus algorithm, this field is strictly enforced to be <= 32 bytes.

bytesmix_hash = 14

MixHash is used to prove, when combined with the nonce that sufficient amount of computation has been achieved and that the solution found is valid.

uint64nonce = 15

Nonce is used to prove, when combined with the mix_hash that sufficient amount of computation has been achieved and that the solution found is valid.

If the Block containing this BlockHeader has been produced using the Proof of Stake consensus algorithm, this field will actually be constant and set to 0.

byteshash = 16

Hash is the hash of the block which is actually the computation:

Keccak256(rlp([ parent_hash, uncle_hash, coinbase, state_root, transactions_root, receipt_root, logs_bloom, difficulty, number, gas_limit, gas_used, timestamp, extra_data, mix_hash, nonce, base_fee_per_gas (to be included only if London fork is active) withdrawals_root (to be included only if Shanghai fork is active) blob_gas_used (to be included only if Cancun fork is active) excess_blob_gas (to be included only if Cancun fork is active) parent_beacon_root (to be included only if Cancun fork is active) requests_hash (to be included only if Prague fork is active) ]))

BigInttotal_difficulty = 17

TotalDifficulty used to be the sum of all previous blocks difficulty including this block difficulty.

It has been deprecated in geth v1.15.0 but was already removed from the JSON-RPC interface for a while

BigIntbase_fee_per_gas = 18

Base fee per gas according to EIP-1559 (e.g. London Fork) rules, only set if London is present/active on the chain.

byteswithdrawals_root = 19

Withdrawals root hash according to EIP-4895 (e.g. Shanghai Fork) rules, only set if Shanghai is present/active on the chain.

Only available in DetailLevel: EXTENDED

Uint64NestedArraytx_dependency = 20

TxDependency is list of transaction indexes that are dependent on each other in the block header. This is metadata only that was used by the internal Polygon parallel execution engine.

This field was available in a few versions on Polygon Mainnet and Polygon Mumbai chains. It was actually removed and is not populated anymore. It's now embedded in the extraData field, refer to Polygon source code to determine how to extract it if you need it.

Only available in DetailLevel: EXTENDED

uint64blob_gas_used = 22

BlobGasUsed was added by EIP-4844 and is ignored in legacy headers.

uint64excess_blob_gas = 23

ExcessBlobGas was added by EIP-4844 and is ignored in legacy headers, this has been added in Cancun hard fork.

bytesparent_beacon_root = 24

ParentBeaconRoot was added by EIP-4788 and is ignored in legacy headers, this has been added in Cancun hard fork.

bytesrequests_hash = 25

RequestsHash was added by EIP-7685 and is ignored in legacy headers, this has been added in Prague hard fork.

uint64slot_number = 26

SlotNumber was added by EIP-7843 and is ignored in legacy headers, it is scheduled to be added in Amsterdam hard fork.

sf.ethereum.type.v2.TransactionTrace

TransactionTrace is full trace of execution of the transaction when the it actually executed on chain.

It contains all the transaction details like from, to, gas, etc. as well as all the internal calls that were made during the transaction.

The calls vector contains Call objects which have balance changes, events storage changes, etc.

If ordering is important between elements, almost each message like Log, Call, StorageChange, etc. have an ordinal field that is represents "execution" order of the said element against all other elements in this block.

Due to how the call tree works doing "naively", looping through all calls then through a Call's element like logs while not yielding the elements in the order they were executed on chain. A log in call could have been done before or after another in another call depending on the actual call tree.

The calls are ordered by creation order and the call tree can be re-computing using fields found in Call object (parent/child relationship).

Another important thing to note is that even if a transaction succeed, some calls within it could have been reverted internally, if this is important to you, you must check the field state_reverted on the Call to determine if it was fully committed to the chain or not.

Note: Some state changes may be present even for failed transactions (see Block documentation for details).

bytesto = 1

consensus

uint64nonce = 2
BigIntgas_price = 3

GasPrice represents the effective price that has been paid for each gas unit of this transaction. Over time, the Ethereum rules changes regarding GasPrice field here. Before London fork, the GasPrice was always set to the fixed gas price. After London fork, this value has different meaning depending on the transaction type (see Type field).

In cases where TransactionTrace.Type == TRX_TYPE_LEGACY || TRX_TYPE_ACCESS_LIST, then GasPrice has the same meaning as before the London fork.

In cases where TransactionTrace.Type == TRX_TYPE_DYNAMIC_FEE, then GasPrice is the effective gas price paid for the transaction which is equals to BlockHeader.BaseFeePerGas + TransactionTrace.

uint64gas_limit = 4

GasLimit is the maximum of gas unit the sender of the transaction is willing to consume when perform the EVM execution of the whole transaction

BigIntvalue = 5

Value is the amount of Ether transferred as part of this transaction.

bytesinput = 6

Input data the transaction will receive for execution of EVM.

bytesv = 7

V is the recovery ID value for the signature Y point.

bytesr = 8

R is the signature's X point on the elliptic curve (32 bytes).

bytess = 9

S is the signature's Y point on the elliptic curve (32 bytes).

uint64gas_used = 10

GasUsed is the total amount of gas unit used for the whole execution of the transaction.

BigIntmax_fee_per_gas = 11

MaxFeePerGas is the maximum fee per gas the user is willing to pay for the transaction gas used.

This will is populated only if TransactionTrace.Type == TRX_TYPE_DYNAMIC_FEE which is possible only if London fork is active on the chain.

Only available in DetailLevel: EXTENDED

Type represents the Ethereum transaction type, available only since EIP-2718 & EIP-2930 activation which happened on Berlin fork. The value is always set even for transaction before Berlin fork because those before the fork are still legacy transactions.

BigIntmax_priority_fee_per_gas = 13

MaxPriorityFeePerGas is priority fee per gas the user to pay in extra to the miner on top of the block's base fee.

This will is populated only if TransactionTrace.Type == TRX_TYPE_DYNAMIC_FEE which is possible only if London fork is active on the chain.

Only available in DetailLevel: EXTENDED

AccessTuple[]access_list = 14

AccessList represents the storage access this transaction has agreed to do in which case those storage access cost less gas unit per access.

This will is populated only if TransactionTrace.Type == TRX_TYPE_ACCESS_LIST || TRX_TYPE_DYNAMIC_FEE which is possible only if Berlin (TRX_TYPE_ACCESS_LIST) nor London (TRX_TYPE_DYNAMIC_FEE) fork are active on the chain.

uint32index = 20

meta

byteshash = 21
bytesfrom = 22
bytesreturn_data = 23

Only available in DetailLevel: EXTENDED Known Issues

  • Version 3:

Field not populated. It will be empty.

Fixed in Version 4, see https://docs.substreams.dev/reference-material/chains-and-endpoints/ethereum-data-model for information about block versions.

bytespublic_key = 24

Only available in DetailLevel: EXTENDED

uint64begin_ordinal = 25

The block's global ordinal when the transaction started executing, refer to Block documentation for further information about ordinals and total ordering.

uint64end_ordinal = 26

The block's global ordinal when the transaction finished executing, refer to Block documentation for further information about ordinals and total ordering.

TransactionTraceStatus is the status of the transaction execution and will let you know if the transaction was successful or not.

Explanation relevant only for blocks with DetailLevel: EXTENDED

A successful transaction has been recorded to the blockchain's state for calls in it that were successful. This means it's possible only a subset of the calls were properly recorded, refer to [calls[].state_reverted] field to determine which calls were reverted.

A quirks of the Ethereum protocol is that a transaction FAILED or REVERTED still affects the blockchain's state for some of the state changes. Indeed, in those cases, the transactions fees are still paid to the miner which means there is a balance change for the transaction's emitter (e.g. from) to pay the gas fees, an optional balance change for gas refunded to the transaction's emitter (e.g. from) and a balance change for the miner who received the transaction fees. There is also a nonce change for the transaction's emitter (e.g. from).

This means that to properly record the state changes for a transaction, you need to conditionally procees the transaction's status.

For a SUCCEEDED transaction, you iterate over the calls array and record the state changes for each call for which state_reverted == false (if a transaction succeeded, the call at #0 will always state_reverted == false because it aligns with the transaction).

For a FAILED or REVERTED transaction, you iterate over the root call (e.g. at #0, will always exist) for balance changes you process those where reason is either REASON_GAS_BUY, REASON_GAS_REFUND or REASON_REWARD_TRANSACTION_FEE and for nonce change, still on the root call, you pick the nonce change which the smallest ordinal (if more than one).

TransactionReceiptreceipt = 31
Call[]calls = 32

Only available in DetailLevel: EXTENDED

uint64blob_gas = 33

BlobGas is the amount of gas the transaction is going to pay for the blobs, this is a computed value equivalent to self.blob_gas_fee_cap * len(self.blob_hashes) and provided in the model for convenience.

This is specified by https://eips.ethereum.org/EIPS/eip-4844

This will is populated only if TransactionTrace.Type == TRX_TYPE_BLOB which is possible only if Cancun fork is active on the chain.

BigIntblob_gas_fee_cap = 34

BlobGasFeeCap is the maximum fee per data gas the user is willing to pay for the data gas used.

This is specified by https://eips.ethereum.org/EIPS/eip-4844

This will is populated only if TransactionTrace.Type == TRX_TYPE_BLOB which is possible only if Cancun fork is active on the chain.

bytes[]blob_hashes = 35

BlobHashes field represents a list of hash outputs from 'kzg_to_versioned_hash' which essentially is a version byte + the sha256 hash of the blob commitment (e.g. BLOB_COMMITMENT_VERSION_KZG + sha256(commitment)[1:].

This is specified by https://eips.ethereum.org/EIPS/eip-4844

This will is populated only if TransactionTrace.Type == TRX_TYPE_BLOB which is possible only if Cancun fork is active on the chain.

SetCodeAuthorization[]set_code_authorizations = 36

SetCodeAuthorizations represents the authorizations of a transaction to set code to an EOA (Externally Owned Accounts) as defined in EIP-7702. The list will contain all the authorizations as they were specified in the transaction itself regardless of their validity. If you need to determined if a given authorization was correctly applied on chain's state, refer to [SetCodeAuthorization.discarded] field that records if the authorization was discarded or not by the chain due to invalidity.

This is specified by https://eips.ethereum.org/EIPS/eip-7702

This will is populated only if TransactionTrace.Type == TRX_TYPE_SET_CODE which is possible only if Prague fork is active on the chain.

sf.ethereum.type.v2.BalanceChange

Note: Balance changes may occur even for failed transactions in certain cases (see Block documentation for details).

bytesaddress = 1

Address is the address of the account that has changed balance.

BigIntold_value = 2

OldValue is the balance of the address before the change. This value can be nil/null/None if there was no previous balance for the address. It is safe in those case(s) to consider the balance as being 0.

If you consume this from a Substreams, you can safely use:

     let old_value = old_value.unwrap_or_default();
BigIntnew_value = 3

NewValue is the balance of the address after the change. This value can be nil/null/None if there was no previous balance for the address after the change. It is safe in those case(s) to consider the balance as being 0.

If you consume this from a Substreams, you can safely use:

     let new_value = new_value.unwrap_or_default();

Reason is the reason why the balance has changed. This is useful to determine why the balance has changed and what is the context of the change.

uint64ordinal = 5

The block's global ordinal when the balance change was recorded, refer to Block documentation for further information about ordinals and total ordering.

sf.ethereum.type.v2.CodeChange

Note: Code changes may have special handling for failed transactions (see Block documentation for details).

bytesaddress = 1
bytesold_hash = 2
bytesold_code = 3
bytesnew_hash = 4
bytesnew_code = 5
uint64ordinal = 6

The block's global ordinal when the code change was recorded, refer to Block documentation for further information about ordinals and total ordering.

sf.ethereum.type.v2.Call

uint32index = 1
uint32parent_index = 2
uint32depth = 3
CallTypecall_type = 4
bytescaller = 5
bytesaddress = 6
BigIntvalue = 7
uint64gas_limit = 8
uint64gas_consumed = 9
boolstatus_failed = 10

In Ethereum, a call can be either:

  • Successful, execution passes without any problem encountered
  • Failed, execution failed, and remaining gas should be consumed
  • Reverted, execution failed, but only gas consumed so far is billed, remaining gas is refunded

When a call is either failed or reverted, the status_failed field below is set to true. If the status is reverted, then both status_failed and status_reverted are going to be set to true.

stringfailure_reason = 11

Populated when a call either failed or reverted, so when status_failed == true, see above for details about those flags.

boolstatus_reverted = 12
bytesreturn_data = 13
bytesinput = 14

Known Issues

  • Version 3:

When call is CREATE or CREATE2, this field is not populated. A couple of suggestions:

  1. You can get the contract's code in the code_changes field.
  2. In the root CREATE call, you can directly use the TransactionTrace's input field.

Fixed in Version 4, see https://docs.substreams.dev/reference-material/chains-and-endpoints/ethereum-data-model for information about block versions.

boolexecuted_code = 15

Indicates whether the call executed code.

Known Issues

  • Version 3:

This may be incorrectly set to false for accounts with code handling native value transfers, as well as for certain precompiles with no input. The value is initially set based on call.type != CREATE && len(call.input) > 0 and later adjusted if the tracer detects an account without code.

Fixed in Version 4, see https://docs.substreams.dev/reference-material/chains-and-endpoints/ethereum-data-model for information about block versions.

boolsuicide = 16
map<string, string>keccak_preimages = 20

hex representation of the hash -> preimage Note: not populated by the Monad tracer, the Monad execution layer does not emit keccak preimage events

StorageChange[]storage_changes = 21

Known Issues

  • Version 3:

The data might be not be in order.

Fixed in Version 4, see https://docs.substreams.dev/reference-material/chains-and-endpoints/ethereum-data-model for information about block versions.

BalanceChange[]balance_changes = 22
NonceChange[]nonce_changes = 24
Log[]logs = 25
CodeChange[]code_changes = 26
GasChange[]gas_changes = 28

Known Issues

  • Version 3:

Some gas changes are not correctly tracked:

  1. Gas refunded due to data returned to the chain (occurs at the end of a transaction, before buyback).
  2. Initial gas allocation (0 -> GasLimit) at the start of a call.
  3. Final gas deduction (LeftOver -> 0) at the end of a call (if applicable).

Fixed in Version 4, see https://docs.substreams.dev/reference-material/chains-and-endpoints/ethereum-data-model for information about block versions.

boolstate_reverted = 30

This field represents whether or not the state changes performed by this call were correctly recorded by the blockchain.

On Ethereum, a transaction can record state changes even if some of its inner nested calls failed. This is problematic however since a call will invalidate all its state changes as well as all state changes performed by its child call. This means that even if a call has a status of SUCCESS, the chain might have reverted all the state changes it performed.

   Trx 1
    Call #1 <Failed>
      Call #2 <Execution Success>
      Call #3 <Execution Success>
      |--- Failure here
    Call #4

In the transaction above, while Call #2 and Call #3 would have the status EXECUTED.

If you check all calls and check only state_reverted flag, you might be missing some balance changes and nonce changes. This is because when a full transaction fails in ethereum (e.g. calls.all(x.state_reverted == true)), there is still the transaction fee that are recorded to the chain.

Refer to [TransactionTrace#status] field for more details about the handling you must perform.

uint64begin_ordinal = 31

Known Issues

  • Version 3:
  1. The block's global ordinal when the call started executing, refer to

Block documentation for further information about ordinals and total ordering.

  1. The transaction root call begin_ordial is always 0 (also in the GENESIS block), which can cause issues

when sorting by this field. To ensure proper execution order, set it as follows: trx.Calls[0].BeginOrdinal = trx.BeginOrdinal.

Fixed in Version 4, see https://docs.substreams.dev/reference-material/chains-and-endpoints/ethereum-data-model for information about block versions.

uint64end_ordinal = 32

Known Issues

  • Version 3:
  1. The block's global ordinal when the call finished executing, refer to

Block documentation for further information about ordinals and total ordering.

  1. The root call of the GENESIS block is always 0. To fix it, you can set it as follows:

rx.Calls[0].EndOrdinal = max.Uint64.

Fixed in Version 4, see https://docs.substreams.dev/reference-material/chains-and-endpoints/ethereum-data-model for information about block versions.

AccountCreation[]account_creations = 33

Known Issues

  • Version 4:

AccountCreations are NOT SUPPORTED anymore. DO NOT rely on them.

bytesaddress_delegates_to = 34

AddressDelegatesTo contains the address from which the actual code to execute will be loaded as defined per EIP-7702 rules. If the Call's address value resolves to a code that delegates to another address, this field will be populated with the address that the call is delegated to. It will be empty in all other situations.

Assumes that a 'SetCode' transaction set address 0xA to delegates to address 0xB, then when a call is made to 0xA, the Call object would have:

  • caller = <from>
  • address = 0xA
  • address_delegates_to = 0xB

Again, it's important to emphasize that this field relates to EIP-7702, if the call is a DELEGATE or CALLCODE type, this field will not be populated and will remain empty.

It will be populated only if EIP-7702 is active on the chain (Prague fork) and if the 'address' of the call was pointing to another address at time of execution.

sf.ethereum.type.v2.Withdrawal

Withdrawal represents a validator withdrawal from the beacon chain to the EVM. Introduced in EIP-4895 (Shanghai hard fork).

uint64index = 1

Index is the monotonically increasing identifier of the withdrawal

uint64validator_index = 2

ValidatorIndex is the index of the validator that is withdrawing

bytesaddress = 3

Address is the Ethereum address receiving the withdrawn funds

uint64amount = 4

Amount is the value of the withdrawal in gwei (1 gwei = 1e9 wei)

sf.ethereum.type.v2.BigInt

bytesbytes = 1

sf.ethereum.type.v2.AccessTuple

AccessTuple represents a list of storage keys for a given contract's address and is used for AccessList construction.

bytesaddress = 1
bytes[]storage_keys = 2

sf.ethereum.type.v2.TransactionReceipt

bytesstate_root = 1

State root is an intermediate state_root hash, computed in-between transactions to make sure you could build a proof and point to state in the middle of a block. Geth client uses PostState + root + PostStateOrStatus while Parity used status_code, root...`` this piles hard forks, see (read the EIPs first):

  • https://github.com/ethereum/EIPs/blob/master/EIPS/eip-658.md

Moreover, the notion of Outcome in parity, which segregates the two concepts, which are stored in the same field status_code` can be computed based on such a hack of the state_root field, following EIP-658`.

Before Byzantinium hard fork, this field is always empty.

uint64cumulative_gas_used = 2
byteslogs_bloom = 3
Log[]logs = 4
uint64blob_gas_used = 5

BlobGasUsed is the amount of blob gas that has been used within this transaction. At time of writing, this is equal to self.blob_gas_fee_cap * len(self.blob_hashes).

This is specified by https://eips.ethereum.org/EIPS/eip-4844

This will is populated only if TransactionTrace.Type == TRX_TYPE_BLOB which is possible only if Cancun fork is active on the chain.

BigIntblob_gas_price = 6

BlobGasPrice is the amount to pay per blob item in the transaction.

This is specified by https://eips.ethereum.org/EIPS/eip-4844

This will is populated only if TransactionTrace.Type == TRX_TYPE_BLOB which is possible only if Cancun fork is active on the chain.

sf.ethereum.type.v2.SetCodeAuthorization

SetCodeAuthorization represents the authorization of a transaction to set code of an EOA (Externally Owned Account) as defined in EIP-7702.

The 'authority' field is the address that is authorizing the delegation mechanism. The 'authority' value is computed from the signature contained in the message using the computation authority = ecrecover(keccak(MAGIC || rlp([chain_id, address, nonce])), y_parity, r, s) where MAGIC is 0x5, || is the bytes concatenation operator, ecrecover is the Ethereum signature recovery and y_parity is the recovery ID value denoted v in the message below. Checking the go-ethereum implementation at https://github.com/ethereum/go-ethereum/blob/v1.15.0/core/types/tx_setcode.go#L117 might prove easier to "read".

We do extract the 'authority' value from the signature in the message and store it in the 'authority' field for convenience so you don't need to perform the computation yourself.

booldiscarded = 1

Discarded determines if this authorization was skipped due to being invalid. As EIP-7702 states, if the authorization is invalid (invalid signature, nonce mismatch, etc.) it must be simply discarded and the transaction is processed as if the authorization was not present in the authorization list.

This boolean records if the authorization was discarded or not by the chain due to invalidity.

byteschain_id = 2

ChainID is the chain ID of the chain where the transaction was executed, used to recover the authority from the signature.

uint64nonce = 3

Nonce is the nonce of the account that is authorizing delegation mechanism, EIP-7702 rules states that nonce should be verified using this rule:

  • Verify the nonce of authority is equal to nonce. In case authority does not exist in the trie,

verify that nonce is equal to 0.

Read SetCodeAuthorization to know how to recover the authority value.

uint32v = 4

V is the recovery ID value for the signature Y point. While it's defined as a uint32, it's actually bounded by a uint8 data type withing the Ethereum protocol.

bytesr = 5

R is the signature's X point on the elliptic curve (32 bytes).

bytess = 6

S is the signature's Y point on the elliptic curve (32 bytes).

bytesauthority = 7

Authority is the address of the account that is authorizing delegation mechanism, it is computed from the signature contained in the message and stored for convenience.

If the authority cannot be recovered from the signature, this field will be empty and the discarded field will be set to true.

bytesaddress = 8

Address contains the address this account is delegating to. This address usually contain code that this account essentially "delegates" to.

Note: This was missing when EIP-7702 was first activated on Holesky, Sepolia, BSC Chapel, BSC Mainnet and Arbitrum Sepolia but was ready for Ethereum Mainnet hard fork. We will backfill those missing values in the near future at which point we will remove this note.

sf.ethereum.type.v2.StorageChange

bytesaddress = 1
byteskey = 2
bytesold_value = 3
bytesnew_value = 4
uint64ordinal = 5

The block's global ordinal when the storage change was recorded, refer to Block documentation for further information about ordinals and total ordering.

sf.ethereum.type.v2.NonceChange

Note: Nonce changes typically persist even for failed transactions (see Block documentation for details).

bytesaddress = 1
uint64old_value = 2
uint64new_value = 3
uint64ordinal = 4

The block's global ordinal when the nonce change was recorded, refer to Block documentation for further information about ordinals and total ordering.

sf.ethereum.type.v2.Log

bytesaddress = 1
bytes[]topics = 2
bytesdata = 3
uint32index = 4

Index is the index of the log relative to the transaction. This index is always populated regardless of the state reversion of the the call that emitted this log.

Only available in DetailLevel: EXTENDED

uint32blockIndex = 6

BlockIndex represents the index of the log relative to the Block.

An important notice is that this field will be 0 when the call that emitted the log has been reverted by the chain.

Currently, there is two locations where a Log can be obtained:

  • block.transaction_traces[].receipt.logs[]
  • block.transaction_traces[].calls[].logs[]

In the receipt case, the logs will be populated only when the call that emitted them has not been reverted by the chain and when in this position, the blockIndex is always populated correctly.

In the case of calls case, for call where stateReverted == true, the blockIndex value will always be 0.

uint64ordinal = 7

The block's global ordinal when the log was recorded, refer to Block documentation for further information about ordinals and total ordering.

sf.ethereum.type.v2.GasChange

The gas change model represents the reason why some gas cost has occurred. The gas is computed per actual op codes. Doing them completely might prove overwhelming in most cases.

Hence, we only index some of them, those that are costy like all the calls one, log events, return data, etc.

uint64old_value = 1
uint64new_value = 2
uint64ordinal = 4

The block's global ordinal when the gas change was recorded, refer to Block documentation for further information about ordinals and total ordering.

sf.ethereum.type.v2.AccountCreation

bytesaccount = 1
uint64ordinal = 2

The block's global ordinal when the account creation was recorded, refer to Block documentation for further information about ordinals and total ordering.

sf.ethereum.type.v2.Uint64Array

uint64[]val = 1

sf.ethereum.type.v2.BalanceChange.Reason

enum

REASON_UNKNOWN = 0

REASON_REWARD_MINE_UNCLE = 1

REASON_REWARD_MINE_UNCLE is a reward for mining an uncle block. Triggered when uncle blocks are processed during block finalization. See: https://github.com/ethereum/go-ethereum/blob/v1.16.4/consensus/ethash/consensus.go#L589

REASON_REWARD_MINE_BLOCK = 2

REASON_REWARD_MINE_BLOCK is a reward for mining a block. Triggered when the block miner receives their mining reward. See: https://github.com/ethereum/go-ethereum/blob/v1.16.4/consensus/ethash/consensus.go#L594

REASON_DAO_REFUND_CONTRACT = 3

REASON_DAO_REFUND_CONTRACT is ether sent to the DAO refund contract. Used during the DAO hard fork to move funds to the refund contract. See: https://github.com/ethereum/go-ethereum/blob/v1.16.4/consensus/misc/dao.go#L85

REASON_DAO_ADJUST_BALANCE = 4

REASON_DAO_ADJUST_BALANCE is ether taken from a DAO account to be moved to the refund contract. Used during the DAO hard fork to extract funds from DAO-related accounts. See: https://github.com/ethereum/go-ethereum/blob/v1.16.4/consensus/misc/dao.go#L86

REASON_TRANSFER = 5

REASON_TRANSFER is ether transferred via a call. This is a decrease for the sender and an increase for the recipient during value transfers. See: https://github.com/ethereum/go-ethereum/blob/v1.16.4/core/evm.go#L144 See: https://github.com/ethereum/go-ethereum/blob/v1.16.4/core/evm.go#L145

REASON_GENESIS_BALANCE = 6

REASON_GENESIS_BALANCE is ether allocated at the genesis block. Triggered when accounts are initialized with balances during genesis block creation. See: https://github.com/ethereum/go-ethereum/blob/v1.16.4/core/genesis.go#L154 See: https://github.com/ethereum/go-ethereum/blob/v1.16.4/core/genesis.go#L180

REASON_GAS_BUY = 7

REASON_GAS_BUY is spent to purchase gas for executing a transaction. The transaction sender's balance is decreased by gasLimit * gasPrice at transaction start. Note: This balance change persists even for failed transactions (see Block documentation). See: https://github.com/ethereum/go-ethereum/blob/v1.16.4/core/state_transition.go#L306

REASON_REWARD_TRANSACTION_FEE = 8

REASON_REWARD_TRANSACTION_FEE is the transaction tip increasing block builder's balance. The coinbase (block miner) receives the transaction fees as a reward. Note: This balance change persists even for failed transactions (see Block documentation). See: https://github.com/ethereum/go-ethereum/blob/v1.16.4/core/state_transition.go#L560

REASON_GAS_REFUND = 9

REASON_GAS_REFUND is ether returned for unused gas at the end of execution. Any unused gas from the transaction is refunded to the sender. Note: This balance change persists even for failed transactions (see Block documentation). See: https://github.com/ethereum/go-ethereum/blob/v1.16.4/core/state_transition.go#L658

REASON_TOUCH_ACCOUNT = 10

REASON_TOUCH_ACCOUNT is a transfer of zero value. It is only there to touch-create an account. Used to create an account without transferring value, often for contract interactions. See: https://github.com/ethereum/go-ethereum/blob/v1.16.4/core/vm/evm.go#L442

REASON_SUICIDE_REFUND = 11

REASON_SUICIDE_REFUND is added to the recipient as indicated by a selfdestructing account. When a contract self-destructs, its remaining balance is sent to a designated recipient. See: https://github.com/ethereum/go-ethereum/blob/v1.16.4/core/vm/instructions.go#L890 See: https://github.com/ethereum/go-ethereum/blob/v1.16.4/core/vm/instructions.go#L910

REASON_CALL_BALANCE_OVERRIDE = 12

REASON_CALL_BALANCE_OVERRIDE represents a balance change due to call balance override. This is a Firehose-specific reason not directly mapped to Geth tracing reasons.

REASON_SUICIDE_WITHDRAW = 13

REASON_SUICIDE_WITHDRAW is deducted from a contract due to self-destruct. The self-destructing contract's balance is reduced to zero. See: https://github.com/ethereum/go-ethereum/blob/v1.16.4/core/vm/instructions.go#L909 See: https://github.com/ethereum/go-ethereum/blob/v1.16.4/core/state/statedb_hooked.go#L230 See: https://github.com/ethereum/go-ethereum/blob/v1.16.4/core/state/statedb_hooked.go#L256

REASON_REWARD_FEE_RESET = 14

REASON_REWARD_FEE_RESET represents a fee reset reward. This is a Firehose-specific reason not directly mapped to Geth tracing reasons.

REASON_BURN = 15

Used on chain(s) where some Ether burning happens This represents ether that is effectively burned when sent to a destroyed contract. See: https://github.com/ethereum/go-ethereum/blob/v1.16.4/core/state/statedb_hooked.go#L288

REASON_WITHDRAWAL = 16

REASON_WITHDRAWAL is ether withdrawn from the beacon chain. Used for validator withdrawals from the Ethereum 2.0 beacon chain to the execution layer. See: https://github.com/ethereum/go-ethereum/blob/v1.16.4/consensus/beacon/consensus.go#L339

REASON_REWARD_BLOB_FEE = 17

Rewards for Blob processing on BNB chain added in Tycho hard-fork, refers to BNB documentation to check the timestamp at which it was activated.

REASON_INCREASE_MINT = 18

This reason is used only on Optimism chain for minting operations.

REASON_REVERT = 19

This reason is used only on Optimism chain for balance reverts.

REASON_MONAD_TX_POST_STATE = 20

This reason is used only on Monad chain. The Monad execution layer does not report the reason for a balance change, only the pre and post-execution state per account. Because of Monad's parallel execution model, there is always exactly one balance change per modified address per transaction, representing the state change. Consumers should not expect granular per-operation entries (i.e. GAS_BUY, TRANSFER, GAS_REFUND, REWARD_TRANSACTION_FEE) because of this.

sf.ethereum.type.v2.Block.DetailLevel

enum

DETAILLEVEL_EXTENDED = 0

DETAILLEVEL_BASE = 2

DETAILLEVEL_TRACE = 1; // TBD

sf.ethereum.type.v2.CallType

enum

UNSPECIFIED = 0

CALL = 1

direct? what's the name for Call alone?

CALLCODE = 2

DELEGATE = 3

STATIC = 4

CREATE = 5

create2 ? any other form of calls?

sf.ethereum.type.v2.GasChange.Reason

enum

REASON_UNKNOWN = 0

REASON_CALL = 1

REASON_CALL is the amount of gas that will be charged for a 'CALL' opcode executed by the EVM. This is an opcode-related gas change mapped from Geth tracing via OnGasChange(gasCopy, gasCopy-cost, tracing.GasChangeCallOpCode). See: https://github.com/streamingfast/go-ethereum/blob/firehose-fh3.0/eth/tracers/firehose.go#L1247-L1264

REASON_CALL_CODE = 2

REASON_CALL_CODE is the amount of gas that will be charged for a 'CALLCODE' opcode executed by the EVM. This is an opcode-related gas change mapped from Geth tracing via OnGasChange(gasCopy, gasCopy-cost, tracing.GasChangeCallOpCode). See: https://github.com/streamingfast/go-ethereum/blob/firehose-fh3.0/eth/tracers/firehose.go#L1247-L1264

REASON_CALL_DATA_COPY = 3

REASON_CALL_DATA_COPY is the amount of gas that will be charged for a 'CALLDATACOPY' opcode executed by the EVM. This is an opcode-related gas change mapped from Geth tracing via OnGasChange(gasCopy, gasCopy-cost, tracing.GasChangeCallOpCode). See: https://github.com/streamingfast/go-ethereum/blob/firehose-fh3.0/eth/tracers/firehose.go#L1247-L1264

REASON_CODE_COPY = 4

REASON_CODE_COPY is the amount of gas that will be charged for a 'CODECOPY' opcode executed by the EVM. This is an opcode-related gas change mapped from Geth tracing via OnGasChange(gasCopy, gasCopy-cost, tracing.GasChangeCallOpCode). See: https://github.com/streamingfast/go-ethereum/blob/firehose-fh3.0/eth/tracers/firehose.go#L1247-L1264

REASON_CODE_STORAGE = 5

REASON_CODE_STORAGE is the amount of gas that will be charged for code storage. Triggered when storing contract code during contract creation. See: https://github.com/ethereum/go-ethereum/blob/v1.16.4/core/vm/evm.go#L593

REASON_CONTRACT_CREATION = 6

REASON_CONTRACT_CREATION is the amount of gas that will be burned for a CREATE opcode. Triggered during contract creation via CREATE opcode, controlled by EIP150 rules. See: https://github.com/ethereum/go-ethereum/blob/v1.16.4/core/vm/instructions.go#L672

REASON_CONTRACT_CREATION2 = 7

REASON_CONTRACT_CREATION2 is the amount of gas that will be burned for a CREATE2 opcode. Triggered during contract creation via CREATE2 opcode, controlled by EIP150 rules. See: https://github.com/ethereum/go-ethereum/blob/v1.16.4/core/vm/instructions.go#L712

REASON_DELEGATE_CALL = 8

REASON_DELEGATE_CALL is the amount of gas that will be charged for a 'DELEGATECALL' opcode executed by the EVM. This is an opcode-related gas change mapped from Geth tracing via OnGasChange(gasCopy, gasCopy-cost, tracing.GasChangeCallOpCode). See: https://github.com/streamingfast/go-ethereum/blob/firehose-fh3.0/eth/tracers/firehose.go#L1247-L1264

REASON_EVENT_LOG = 9

REASON_EVENT_LOG is the amount of gas that will be charged for a 'LOG<N>' opcode executed by the EVM. This is an opcode-related gas change mapped from Geth tracing via OnGasChange(gasCopy, gasCopy-cost, tracing.GasChangeCallOpCode). See: https://github.com/streamingfast/go-ethereum/blob/firehose-fh3.0/eth/tracers/firehose.go#L1247-L1264

REASON_EXT_CODE_COPY = 10

REASON_EXT_CODE_COPY is the amount of gas that will be charged for an 'EXTCODECOPY' opcode executed by the EVM. This is an opcode-related gas change mapped from Geth tracing via OnGasChange(gasCopy, gasCopy-cost, tracing.GasChangeCallOpCode). See: https://github.com/streamingfast/go-ethereum/blob/firehose-fh3.0/eth/tracers/firehose.go#L1247-L1264

REASON_FAILED_EXECUTION = 11

REASON_FAILED_EXECUTION is the burning of the remaining gas when the execution failed without a revert. Triggered when a call fails and all remaining gas is consumed. See: https://github.com/ethereum/go-ethereum/blob/v1.16.4/core/vm/evm.go#L308 See: https://github.com/ethereum/go-ethereum/blob/v1.16.4/core/vm/evm.go#L363 See: https://github.com/ethereum/go-ethereum/blob/v1.16.4/core/vm/evm.go#L407 See: https://github.com/ethereum/go-ethereum/blob/v1.16.4/core/vm/evm.go#L462 See: https://github.com/ethereum/go-ethereum/blob/v1.16.4/core/vm/evm.go#L521 See: https://github.com/ethereum/go-ethereum/blob/v1.16.4/core/vm/evm.go#L567

REASON_INTRINSIC_GAS = 12

REASON_INTRINSIC_GAS is the amount of gas charged for the intrinsic cost of the transaction. There is always exactly one of these per transaction, representing the base cost. See: https://github.com/ethereum/go-ethereum/blob/v1.16.4/core/state_transition.go#L464

REASON_PRECOMPILED_CONTRACT = 13

REASON_PRECOMPILED_CONTRACT is the amount of gas charged for a precompiled contract execution. Triggered when calling precompiled contracts (addresses 0x01-0x09, etc.). See: https://github.com/ethereum/go-ethereum/blob/v1.16.4/core/vm/contracts.go#L271

REASON_REFUND_AFTER_EXECUTION = 14

REASON_REFUND_AFTER_EXECUTION is the amount of gas refunded to the caller after call execution. Triggered when gas is refunded after a successful call completes. See: https://github.com/ethereum/go-ethereum/blob/v1.16.4/core/vm/instructions.go#L688 See: https://github.com/ethereum/go-ethereum/blob/v1.16.4/core/vm/instructions.go#L724 See: https://github.com/ethereum/go-ethereum/blob/v1.16.4/core/vm/instructions.go#L764 See: https://github.com/ethereum/go-ethereum/blob/v1.16.4/core/vm/instructions.go#L797 See: https://github.com/ethereum/go-ethereum/blob/v1.16.4/core/vm/instructions.go#L826 See: https://github.com/ethereum/go-ethereum/blob/v1.16.4/core/vm/instructions.go#L855

REASON_RETURN = 15

REASON_RETURN is the amount of gas that will be charged for a 'RETURN' opcode executed by the EVM. This is an opcode-related gas change mapped from Geth tracing via OnGasChange(gasCopy, gasCopy-cost, tracing.GasChangeCallOpCode). See: https://github.com/streamingfast/go-ethereum/blob/firehose-fh3.0/eth/tracers/firehose.go#L1247-L1264

REASON_RETURN_DATA_COPY = 16

REASON_RETURN_DATA_COPY is the amount of gas that will be charged for a 'RETURNDATACOPY' opcode executed by the EVM. This is an opcode-related gas change mapped from Geth tracing via OnGasChange(gasCopy, gasCopy-cost, tracing.GasChangeCallOpCode). See: https://github.com/streamingfast/go-ethereum/blob/firehose-fh3.0/eth/tracers/firehose.go#L1247-L1264

REASON_REVERT = 17

REASON_REVERT is the amount of gas that will be charged for a 'REVERT' opcode executed by the EVM. This is an opcode-related gas change mapped from Geth tracing via OnGasChange(gasCopy, gasCopy-cost, tracing.GasChangeCallOpCode). See: https://github.com/streamingfast/go-ethereum/blob/firehose-fh3.0/eth/tracers/firehose.go#L1247-L1264

REASON_SELF_DESTRUCT = 18

REASON_SELF_DESTRUCT is the amount of gas that will be charged for a 'SELFDESTRUCT' opcode executed by the EVM. This is an opcode-related gas change mapped from Geth tracing via OnGasChange(gasCopy, gasCopy-cost, tracing.GasChangeCallOpCode). See: https://github.com/streamingfast/go-ethereum/blob/firehose-fh3.0/eth/tracers/firehose.go#L1247-L1264

REASON_STATIC_CALL = 19

REASON_STATIC_CALL is the amount of gas that will be charged for a 'STATICCALL' opcode executed by the EVM. This is an opcode-related gas change mapped from Geth tracing via OnGasChange(gasCopy, gasCopy-cost, tracing.GasChangeCallOpCode). See: https://github.com/streamingfast/go-ethereum/blob/firehose-fh3.0/eth/tracers/firehose.go#L1247-L1264

REASON_STATE_COLD_ACCESS = 20

REASON_STATE_COLD_ACCESS is the amount of gas charged for a cold storage access as controlled by EIP2929 rules. Triggered when accessing storage slots or accounts that haven't been accessed in the current transaction. Added in Berlin fork (Geth 1.10+) See: https://github.com/ethereum/go-ethereum/blob/v1.16.4/core/vm/operations_acl.go#L167 See: https://github.com/ethereum/go-ethereum/blob/v1.16.4/core/vm/operations_acl.go#L268 See: https://github.com/ethereum/go-ethereum/blob/v1.16.4/core/vm/operations_acl.go#L283

REASON_TX_INITIAL_BALANCE = 21

REASON_TX_INITIAL_BALANCE is the initial gas balance for the transaction equal to the gasLimit. There is only one such gas change per transaction, representing the initial gas allocation. See: https://github.com/ethereum/go-ethereum/blob/v1.16.4/core/state_transition.go#L300

REASON_TX_REFUNDS = 22

REASON_TX_REFUNDS is the sum of all refunds during transaction execution (e.g. storage slot clearing). This generates an increase in gas. There is only one such gas change per transaction. See: https://github.com/ethereum/go-ethereum/blob/v1.16.4/core/state_transition.go#L648

REASON_TX_LEFT_OVER_RETURNED = 23

REASON_TX_LEFT_OVER_RETURNED is the amount of gas left over at transaction end that will be returned. This change will always be negative as we "drain" left over gas towards 0. If there was no gas left at the end of execution, no such event will be emitted. There is at most one per transaction. See: https://github.com/ethereum/go-ethereum/blob/v1.16.4/core/state_transition.go#L661

REASON_CALL_INITIAL_BALANCE = 24

REASON_CALL_INITIAL_BALANCE is the initial gas balance for a call equal to the gasLimit of the call. There is only one such gas change per call. See: https://github.com/ethereum/go-ethereum/blob/v1.16.4/core/vm/evm.go#L662

REASON_CALL_LEFT_OVER_RETURNED = 25

REASON_CALL_LEFT_OVER_RETURNED is the amount of gas left over that will be returned to the caller. This change will always be negative as we "drain" left over gas towards 0. If there was no gas left at the end of execution, no such event will be emitted. See: https://github.com/ethereum/go-ethereum/blob/v1.16.4/core/vm/evm.go#L669

REASON_WITNESS_CONTRACT_INIT = 26

REASON_WITNESS_CONTRACT_INIT flags the event of adding to the witness during contract creation initialization. Used in stateless Ethereum (Verkle trees) for witness data collection. See: https://github.com/ethereum/go-ethereum/blob/v1.16.4/core/vm/evm.go#L548

REASON_WITNESS_CONTRACT_CREATION = 27

REASON_WITNESS_CONTRACT_CREATION flags the event of adding to the witness during contract creation finalization. Used in stateless Ethereum (Verkle trees) for witness data collection. This is a Firehose-specific reason not directly mapped to current Geth tracing reasons.

REASON_WITNESS_CODE_CHUNK = 28

REASON_WITNESS_CODE_CHUNK flags the event of adding one or more contract code chunks to the witness. Used in stateless Ethereum (Verkle trees) for witness data collection. See: https://github.com/ethereum/go-ethereum/blob/v1.16.4/core/vm/evm.go#L598 See: https://github.com/ethereum/go-ethereum/blob/v1.16.4/core/vm/interpreter.go#L179

REASON_WITNESS_CONTRACT_COLLISION_CHECK = 29

REASON_WITNESS_CONTRACT_COLLISION_CHECK flags the event of adding to the witness when checking for contract address collision. Used in stateless Ethereum (Verkle trees) for witness data collection. See: https://github.com/ethereum/go-ethereum/blob/v1.16.4/core/vm/evm.go#L500

REASON_TX_DATA_FLOOR = 30

REASON_TX_DATA_FLOOR is the amount of extra gas the transaction has to pay to reach the minimum gas requirement. This change will always be negative and represents additional gas cost for transaction data. See: https://github.com/ethereum/go-ethereum/blob/v1.16.4/core/state_transition.go#L538

sf.ethereum.type.v2.TransactionTrace.Type

enum

TRX_TYPE_LEGACY = 0

All transactions that ever existed prior Berlin fork before EIP-2718 was implemented.

TRX_TYPE_ACCESS_LIST = 1

Transaction that specicy an access list of contract/storage_keys that is going to be used in this transaction.

Added in Berlin fork (EIP-2930).

TRX_TYPE_DYNAMIC_FEE = 2

Transaction that specifis an access list just like TRX_TYPE_ACCESS_LIST but in addition defines the max base gas gee and max priority gas fee to pay for this transaction. Transaction's of those type are executed against EIP-1559 rules which dictates a dynamic gas cost based on the congestion of the network.

TRX_TYPE_BLOB = 3

Transaction which contain a large amount of data that cannot be accessed by EVM execution, but whose commitment can be accessed. The format is intended to be fully compatible with the format that will be used in full sharding.

Transaction that defines an access list just like TRX_TYPE_ACCESS_LIST and enables dynamic fee just like TRX_TYPE_DYNAMIC_FEE but in addition defines the fields 'max_fee_per_data_gas' of type 'uint256' and the fields 'blob_versioned_hashes' which represents a list of hash outputs from 'kzg_to_versioned_hash'.

Activated in Cancun fork (EIP-4844)

TRX_TYPE_SET_CODE = 4

Transaction that sets code to an EOA (Externally Owned Accounts)

Activated in Prague (EIP-7702)

TRX_TYPE_ARBITRUM_DEPOSIT = 100

Arbitrum-specific transactions

TRX_TYPE_ARBITRUM_UNSIGNED = 101

TRX_TYPE_ARBITRUM_CONTRACT = 102

TRX_TYPE_ARBITRUM_RETRY = 104

TRX_TYPE_ARBITRUM_SUBMIT_RETRYABLE = 105

TRX_TYPE_ARBITRUM_INTERNAL = 106

TRX_TYPE_ARBITRUM_LEGACY = 120

TRX_TYPE_OPTIMISM_DEPOSIT = 126

OPTIMISM-specific transactions

TRX_TYPE_POLYGON_STATE_SYNC = 200

Polygon(bor)-specific

sf.ethereum.type.v2.TransactionTraceStatus

enum

UNKNOWN = 0

SUCCEEDED = 1

FAILED = 2

REVERTED = 3