Open this lesson in your favourite AI. It'll walk you through the why, explain the demo, and quiz you on the try-it list.
Bitcoin is not an account ledger; it's a set of unspent outputs. A transaction destroys some UTXOs and creates new ones, and the difference is the fee. Understanding this model from the ground up is the foundation for everything — wallet design, scaling, privacy, scripts. Account-model intuition from Ethereum will mislead you here.
A minimal transaction inspection.
Use these three in order. Each builds on the one before.
In one paragraph, explain the UTXO model and how it differs from accounts.
Walk me through what happens to UTXOs when I send 0.5 BTC and have a 1 BTC UTXO.
Given a wallet with 200 small UTXOs and a need to send 0.1 BTC, what's the optimal coin-selection strategy and why?
# bitcoinlib / python-bitcoinlib decoding of a real mainnet tx
# A coinbase reward tx (block 100,000) — pure UTXO creation, no inputs spent
import json
import urllib.request
def fetch_tx(txid: str):
url = f"https://blockstream.info/api/tx/{txid}"
with urllib.request.urlopen(url) as r:
return json.loads(r.read())
# Example mainnet tx (one of Satoshi's early txs):
tx = fetch_tx("f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16")
print("vin count:", len(tx["vin"]))
print("vout count:", len(tx["vout"]))
for i, out in enumerate(tx["vout"]):
print(f" vout[{i}]: value={out['value']} sats, addr={out.get('scriptpubkey_address')}")
for i, inp in enumerate(tx["vin"]):
prev = inp.get("prevout", {})
print(f" vin[{i}]: spends={inp['txid']}:{inp['vout']} value={prev.get('value')} sats")
# A Bitcoin tx is: inputs (UTXOs being spent) + outputs (new UTXOs) + signatures
# fee = sum(inputs) - sum(outputs)
# The whole chain is just a graph of UTXOs flowing into and out of transactions.