This is a read note of Programming Bitcoin Ch05: Transactions.

1 Transaction Components

At a high level, a transaction really only has four components. They are:

  1. Version: indicates what additional features the transaction uses. Often this is 1 but some use 2 with OP_CHECKSEQUENCEVERIFY defined BIP0112.
  2. Inputs: define what bitcoins are being spent.
  3. Outputs: define where the bitcoins are going.
  4. Locktime: defines when this transaction starts being valid.

2 Inputs

Each input needs two things:

  • A reference to bitcoins you received previously
  • Proof that these are yours to spend

The inputs field can contain more than one input. The first part is an varint (variable integer) that specifies the number of inputs. Variable integers work by these rules:

  • If the number is below 253, encode that number as a single byte (e.g., 100 → 0x64).
  • If the number is between 253 and 2 ** 16 – 1, start with the 253 byte (fd) and then encode the number in 2 bytes in little-endian (e.g., 255 → 0xfdff00, 555 → 0xfd2b02).
  • If the number is between 2 ** 16 and 2 ** 32 – 1, start with the 254 byte (fe) and then encode the number in 4 bytes in little-endian (e.g., 70015 → 0xfe7f110100).
  • If the number is between 2 ** 32 and 2 ** 64 – 1, start with the 255 byte (ff) and then encode the number in 8 bytes in little-endian (e.g., 18005558675309 → 0xff6dc7ed3e60100000).

Each input contains four fields. The first two fields point to the previous transaction output and the last two fields define how the previous transaction output can be spent. The fields are as follows:

  • Previous transaction ID: the hash256 of the previous transaction’s contents. 32 bytes in little endian.
  • Previous transaction index: the index of the previous transaction’s outputs. 4 bytes in little endian.
  • ScriptSig: a variable-length script to unlock the input.
  • Sequence: originally intended by Satoshi to do “highfrequency trades” with the locktime field, but is currently used with Replace-By-Fee (RBF) and OP_CHECKSEQUENCEVERIFY. The sequence is also in little-endian and takes up 4 bytes.

3 Outputs

Each transaction must have one or more outputs. Like with inputs, output serialization starts with how many outputs there are as a varint.

Each output has two fields: amount and ScriptPubKey. The amount is the amount of bitcoins being assigned and is specified in satoshis, or 1/100,000,000ths of a bitcoin. This number is greater than 2 ** 32 (4.3 billion or so) and is thus stored in 64 bits, or 8 bytes. The amount is serialized in little-endian.

The ScriptPubKey, like the ScriptSig, has to do with Bitcoin’s smart contract language, Script. Think of the ScriptPubKey as the locked box that can only be opened by the holder of the key. It’s like a one-way safe that can receive deposits from anyone, but can only be opened by the owner of the safe.

UTXO stands for unspent transaction output. The entire set of unspent transaction outputs at any given moment is called the UTXO set. At any moment in time, they represent all the bitcoins that are available to be spent.

4 Locktime

Locktime is a way to time-delay a transaction. A transaction with a locktime of 600,000 cannot go into the blockchain until block 600,001. This was originally construed as a way to do high-frequency trades, which turned out to be insecure. If the locktime is greater than or equal to 500,000,000, it’s a Unix timestamp. If it’s less than 500,000,000, it’s a block number. This way, transactions can be signed but unspendable until a certain point in Unix time or block height is reached. The uses before BIP0065 were limited. BIP0065 introduced OP_CHECKLOCKTIMEVERIFY, which makes locktime more useful by making an output unspendable until a certain locktime.

The serialization is in little-endian and 4 bytes.

5 Transaction Fee

One of the consensus rules of Bitcoin is that for any non-coinbase transactions, the sum of the inputs has to be greater than or equal to the sum of the outputs to pay a transaction fee that is used to incentivize miners to include transactions.

The transaction fee is simply the sum of the inputs minus the sum of the outputs. This difference is what the miner gets to keep.

To get the amount of the input transactions, one needs to get the entire transaction and verify its id before use its amount.