MASTERING-BITCOIN ยท Interactive Practice | Unit 6 ยท Video 2

Bitcoin Transaction Inputs: Outpoints, UTXOs, and Double Spending

IKey Reference

Outpoint anatomy โ€” a 36-byte pointer to exactly one previous output:

Field Size Purpose
txid 32 bytes Identifies the previous transaction
output index 4 bytes Selects which output within that transaction

compactSize encoding โ€” Bitcoin's variable-length integer encoding:

Value Range Prefix Byte Total Bytes
0โ€“252 (none) 1
253โ€“65,535 0xfd 3
65,536โ€“4,294,967,295 0xfe 5
4,294,967,296+ 0xff 9

Core rule: A transaction is valid only if every input's outpoint references an output that currently exists in the UTXO (Unspent Transaction Output) database.

IIVisualization 1: How compactSize Encodes Numbers

Bitcoin uses compactSize to encode counts (like the number of inputs in a transaction) using as few bytes as possible. Pick a value to see how it gets encoded.

Reflect: Why is compactSize designed so that small values (which are by far the most common) take only one byte, while only large values pay the cost of extra bytes?

โš™ interactive visualization โ€” coming to this page format soon

IIIVisualization 2: The UTXO Database in Action

A full node validates each transaction by checking that every input's outpoint references an output that is still in the UTXO database. Try the three scenarios below to see how the node responds.

Notice: the UTXO database โ€” not miners โ€” is what enforces the no-double-spend rule. Every full node maintains its own copy and rejects invalid transactions independently.

โš™ interactive visualization โ€” coming to this page format soon

IVVisualization 3: txid Byte Order โ€” Little-Endian vs Big-Endian

Inside a serialized transaction, txids are stored in little-endian byte order. But block explorers and bitcoin-cli display them in big-endian order โ€” the full 32-byte sequence reversed. Pick an example to see what this looks like.

Notice: the bytes are not partially reversed and they are not displayed as-is โ€” the entire 32-byte sequence is reversed end-to-end.

โš™ interactive visualization โ€” coming to this page format soon

VQuiz Questions

Question 1

A transaction has 300 inputs. The number of inputs is encoded with compactSize at the start of the transaction. How many total bytes does this count field occupy?

โœ… Correct! 300 is above 252, so compactSize uses the 0xfd prefix plus 2 data bytes โ€” 3 bytes total.

โŒ Not quite. A single byte only fits values 0โ€“252. 300 is just over that limit.

โŒ Not quite. 300 is small enough to fit in the 3-byte encoding (0xfd + 2 data bytes). The 5- and 9-byte encodings are reserved for much larger values.

Show solution

Solution:

The value 300 falls in the range 253โ€“65,535, so compactSize uses:

  • 1 prefix byte: 0xfd
  • 2 data bytes: 300 in little-endian is 2c 01

Total: 3 bytes.

Only values 0โ€“252 fit in a single byte with no prefix.

Question 2

An outpoint is the field in a transaction input that points to the previous output being spent. Which option correctly describes the outpoint's structure and total size?

โœ… Correct! An outpoint is just txid (32) + output index (4) = 36 bytes. The input itself carries no amount; the node looks the amount up in the UTXO database.

โŒ Not quite. The amount is not stored in the input. Inputs hold no value on their own โ€” they only point to a previous output, and the node looks the amount up in the UTXO database.

โŒ Not quite. Check the field sizes: txid is 32 bytes (a full hash) and the output index is 4 bytes.

Show solution

Solution:

An outpoint is a pointer, not a value. It contains exactly two fields:

  • txid (32 bytes) โ€” identifies the previous transaction
  • output index (4 bytes) โ€” selects which output within that transaction

Total: 36 bytes.

The amount is not part of the outpoint. The node looks the amount up in the UTXO database after using the outpoint to find the referenced output.

Question 3

True or False: Miners are the primary mechanism that prevents double-spending in Bitcoin. If a miner accepts a double-spend transaction into a block, the rest of the network is forced to accept it.

โœ… Correct! Every full node enforces the no-double-spend rule independently. A miner who includes a double-spend just produces a block that the rest of the network rejects.

โŒ Not quite. This is a common misconception. Miners order transactions, but the no-double-spend rule is enforced by every full node against its own UTXO database. A block containing a double-spend is rejected by the network.

โŒ Not quite. Try again โ€” the hints above can help.

Show solution

Solution:

False. Every full node enforces the no-double-spend rule independently by maintaining its own UTXO database.

When a node receives a new block:

  1. For every input, it removes the referenced output from its UTXO database.
  2. For every new output, it adds it to its UTXO database.
  3. Any transaction referencing an output that is no longer in the database fails validation.

If a miner produces a block containing a double-spend, every other full node detects the conflict and rejects the entire block as invalid โ€” the malicious miner wastes their work. Mining provides ordering and finality, but the actual double-spend prevention is enforced by every node, every time.

Question 4

A serialized transaction stores a txid as 32 bytes in little-endian order, beginning with 1a 2b 3c 4d ... and ending with ... e7 f8.

What does the same txid look like when displayed in a block explorer (big-endian)?

โœ… Correct! The full 32-byte sequence is reversed end-to-end, so the byte that was first in the serialized txid is last in the displayed txid.

โŒ Not quite. Display tools and the serialized format use different byte orders. That mismatch is exactly what trips up developers: a copy-pasted little-endian txid won't be found by bitcoin-cli.

โŒ Not quite. It isn't a partial reversal โ€” all 32 bytes are reversed end-to-end. The first byte becomes the last byte.

โŒ Not quite. It's not a pairwise swap โ€” the whole 32-byte sequence is reversed end-to-end.

Show solution

Solution:

To convert between little-endian (serialized) and big-endian (display), you reverse the entire 32-byte sequence end-to-end. The byte that was first becomes last, and vice versa.

If the serialized form is:

1a 2b 3c 4d ... e7 f8

then the display form is:

f8 e7 ... 4d 3c 2b 1a

This is the most common pitfall when working with raw transactions:

  • Pasting a little-endian txid into bitcoin-cli getrawtransaction returns "No such mempool or blockchain transaction".
  • Reversing all 32 bytes first gives the value the CLI expects.

This quirk is an artifact of Bitcoin's earliest code and is now permanent.

Solved: 0 / 4