# Transactions and Blocks

This subchapter explains the structure of blocks, transactions, and how both are properly parsed within BDK and AppLayer.

## How transactions are parsed

No matter the type, there are two ways a transaction can be parsed from a bytes string:

* *Directly from RLP*
  * Requires deriving the sender (`from`) address and a validity check using secp256k1
  * *Not* included in a block, which means it's a new transaction coming from the network
  * Equivalent to Ethereum's `rawTransaction`
* *Directly from the database*
  * Considered trustworthy since it already went through the process above
  * *Is* included in a block, therefore it's part of the blockchain

## Transaction structure

Depending on the type, a transaction will contain the following data fields once it's properly parsed:

* **(TxBlock) to** - receiver address (the one that received the funds)
* **(Both) from** - sender address (the one that sent the funds)
* **(Both) data** - arbitrary data field (used in contracts)
* **(Both) chainId** - unique blockchain ID where the transaction was made
* **(TxValidator) nHeight** - height of the block where the transaction was included
* **(TxBlock) nonce** - number of the transaction made from the sender address - always starts at 0, so a nonce of `4` means this is the *fifth* transaction from the address
* **(TxBlock) value** - transaction value in its lowest unit
  * e.g. "satoshi" for BTC, "Wei" for ETH, etc. - "100000000" satoshis would be 1 BTC, "5000000000" Wei would be 0.000000005 ETH (or 5 gwei), so on and so forth
  * Since we're using an Ethereum-based format, we commonly refer to its terminology, so "value" is in "Wei"
* **(TxBlock) maxPriorityFeePerGas** - value paid as an incentive for miners to include the transaction in the block, as per [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559)
  * This is implemented but actively ignored since we don't have "miners", therefore only maxFeePerGas is counted
* **(TxBlock) maxFeePerGas** - value paid by every unit of gas, in Gwei (e.g. "15" = 15000000000 Wei)
  * The total transaction fee is calculated as (gasLimit \* maxFeePerGas) - e.g. 21000 \* 15000000000 = 0.000315 ETH
* **(TxBlock) gasLimit** - maximum limit of gas units that the transaction will use, in Wei (e.g. "21000")
  * If the transaction uses more than this limit, it will automatically fail - the original transaction value won't be spent, but what was already spent as gas is lost
* **(Both)** ECDSA signature (Elliptic Curve Digital Signature Algorithm) for validating transaction integrity, split in three:
  * **r** - first half of the ECDSA signature (32 hex bytes)
  * **s** - second half of the ECDSA signature (32 hex bytes)
  * **v** - recovery ID (1 hex byte)
* **(Both) hash** - The transaction's own hash (including the signature), stored as a cache for performance reasons

## Block structure

A block will contain the following conceptual structure:

* Validator signature (the one responsible for creating and signing the block)
* Validator public key (for verifying the signature)
* The block's header, which is made of:
  * Previous block hash (a hash of the previous block's header, signed by the Validator)
  * "Randomness" (a random seed generated by RandomGen during the previous block's creation)
  * Validator Tx Merkle Tree (to verify the integrity of Validator transactions)
  * Block Tx Merkle Tree (to verify the integrity of Block transactions)
  * UNIX timestamp of the block, in microseconds
  * Block height (commonly known as `nHeight`)
* List of Validator transactions
* List of block transactions
* A cached hash of the block's header
* The total size of the block, in bytes

In practice, a block is simply a serialized bytes string, transmitted through the network and stored in the blockchain, so it's up to the code logic to properly parse it. Another way to see the block in a more "raw" format would be ("bytes" are in hex format, e.g. `0xFF` = 1 byte):

```
Outside header:
  65 bytes - Validator signature
  65 bytes - Validator public key
Header (144 bytes):
  32 bytes - Previous block hash
  32 bytes - "Randomness"
  32 bytes - Validator Tx Merkle Root
  32 bytes - Block Tx Merkle Root
  8 bytes - Timestamp (in microseconds)
  8 bytes - Block height
Content:
  8 bytes - Offset of Validator transactions array
  [
    4 bytes - Block transaction size
    N bytes - Block transaction
    ...
  ]
  [
    4 bytes - Validator transaction size
    N bytes - Validator transaction
    ...
  ]
```

Blocks transmitted through the network *must* have the Validator signature, which is part of the block but is *outside* its structure. This is intentional, so the block header can be hashed and signed on its own without hashing the signature along with it.

## Raw block analysis

A "raw" finalized block would look something like this:

`5c37d504e9415c3b75afaa3ad24484382274bba31f10dcd268e554785d5b807500000181810eb6507a8b54dfbfe9f21d00000001000000aff8ad81be850c92a69c0082e18c94d586e7f844cea2f87f50152665bcbc2c279d8d7080b844a9059cbb00000000000000000000000026548521f99d0709f615aa0f766a7df60f99250b00000000000000000000000000000000000000000000002086ac351052600000830150f7a07e16328b7f3823abeb13d0cab11cdffaf967c9b2eaf3757c42606d6f2ecd8ce6a040684c94b289cdda2282...`

Where:

* Validator signature = `5c37d504e9415c3b75afaa3ad24484382274bba31f10dcd268e554785d5b807500000181810eb6507a8b54dfbfe9f21d00000001000000aff8ad81be850c92a69c`
* Previous block hash = `0082e18c94d586e7f844cea2f87f50152665bcbc2c279d8d7080b844a9059cbb`
* "Randomness" = `00000000000000000000000026548521f99d0709f615aa0f766a7df60f99250b`
* Validator Merkle Tree = `00000000000000000000000000000000000000000000002086ac351052600000`
* Block Merkle Tree = `830150f7a07e16328b7f3823abeb13d0cab11cdffaf967c9b2eaf3757c42606d`
* Timestamp = `6f2ecd8ce6a04068`
* Block height = `4c94b289cdda2282`
* Rest of the content = `...`


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.applayer.com/testnet/bdk-implementation/transactions-and-blocks.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
