# 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 = `...`
