“Transactions are the most important part of the Bitcoin system. Everything else in bitcoin is designed to ensure that transactions can be created, propagated on the network, validated, and finally added to the global ledger of transactions (the blockchain). Each transaction is a public entry in Bitcoin’s blockchain, the global double-entry bookkeeping ledger.” — Andreas Antonopoulos
I learned a lot of how Bitcoin works through Mastering Bitcoin 2nd Edition. This was a fantastic book and I highly recommend it. The book contains very detailed explanations and mathematics of the inner workings of Bitcoin. There is a lot content throughout the book so I wanted to distill the most important information. In order to get a good picture of the whole Bitcoin system, I think it’s important to first grasp the concept of transactions.
Transactions in bitcoin are modelled differently than how they are conventionally modelled in financial systems today. For example, when I transfer $10 to Bob, the transaction would be modelled as a debit of $10 from my account balance and a $10 credit to Bob’s account balance. Bitcoin uses a different transaction model based on transaction outputs.
A transaction output can be thought of as an amount of money that has an owner assigned to it. The money in this case is an amount of satoshis (1 Bitcoin (BTC) = 100,000,000 satoshis ) and the owner is determined by the bitcoin wallet address on the output. A transaction output can either be spent or unspent. Any bitcoin that hasn’t been spent yet is called an unspent transaction output (UTXO). The entire state of the Bitcoin system consists of a set of everyone’s transaction outputs.
Properties of a UTXO:
- A transaction output is an indivisible unit, meaning you cannot divide an output into parts and spend one of the parts
- When a UTXO is spent, it cannot be spent again.
Let’s do a simple transaction as an example:
Alice wants to send Bob 0.01 BTC and Alice uses her UTXO worth 0.03 BTC. Since Alice’s 0.03 BTC is indivisible, she will get some BTC back as “change”. Bob will get an output worth 0.01 BTC and Alice will get an output worth 0.02 BTC back as change. The original output worth 0.03 BTC is marked as spent. In the end, Alice has ended up with a new output worth 0.02 BTC. This transaction is similar to making a real-life purchase using bills. If I want to buy milk worth $4.50 and I pay using a $5 bill, I will get 50 cents back as change.
And that all what transactions are — inputs and outputs of UTXO. Pretty simple right? Now what’s to stop a malicious attacker from modifying transactions such as changing the transaction amounts and spending a UTXO that does not belong to them? To answer this, we need to look deeper into what the above Bitcoin transaction really looks like:
That might have been hard to parse..You may have noticed that there are no addresses included within the transaction. Where is Bob’s address? Where is the 0.03 BTC sent by Alice? Let’s break this transaction down.
A transaction is composed of inputs and outputs. The names speak for themselves — they are what goes into the transaction and what comes out.
- vout contains the list of outputs. Each output is a UTXO containing a value and a locking script: scriptPubKey. A locking script is a spending condition that must be satisfied in order to spend the UTXO. This prevents anyone random from trying to spend the UTXO. One would need another script called the unlocking script to “solve” or satisfy, this UTXO — more on this topic below.
- vin contains the list of inputs. An input is a reference (pointer) to another transaction. Each transaction has a unique identifier, txid which is calculated by taking the hash of the transaction object. vout specifies the specific output of that transaction. So with txid and vout, the desired UTXO is then known. An additional lookup by the wallet is needed to retrieve the UTXO from the txid. scriptSig is the unlocking script that is needed to spend the referenced UTXO.
Script is Bitcoin’s Turing incomplete language which means that the language cannot run every possible algorithm. For instance, Script doesn’t support loops. This is necessary to prevent any infinite loops from happening. Both the locking and unlocking scripts are written using this scripting language.
Today, the most commonly used script called the Pay-to-Public-Key-Hash script (P2PKH). This is simply a function that takes in arguments and if they satisfy the function, then we will be able to pay to the recipient’s bitcoin address. An example of how the script actually executes can be found here.
Let’s see how scripts are constructed in the example above where Alice sends 0.01 BTC to Bob. Alice’s wallet needs to construct the transaction’s inputs and outputs. Alice’s wallet first finds a UTXO that is greater than or equal to 0.01 BTC. In this case, the wallet uses a UTXO worth 0.03 BTC. The wallet constructs the outputs scripts as:
This sets Bob’s public key in a locking script to the 0.01 BTC and Alice’s public key in a locking script to the 0.02 BTC. The public keys are addresses that are generated by each individual’s bitcoin wallet.
For the input unlocking script (scriptSig), the wallet sets it as:
<Alice’s Digital Signature> <Alice’s Public Key>
The digit signature is created using Alice’s private key to sign the contents of the current transaction (excluding inputs because the signature is in the input) and the hash of the previous transactions. A digital signature serves two purposes:
- It prevents the current transaction from being modified. If the transaction gets modified, the value in the scriptSig won’t match.
- The signature proves that the owner of the private key, is in fact the owner of the UTXO that they are willing to spend.
So together, the two scripts form:
<Alice's Digital Signature> <Alice's Public Key> OP_DUP OP_HASH160
<Alice's Public Key Hash> OP_EQUALVERIFY OP_CHECKSIG
By running these scripts, anyone can verify that the transaction was authorized by Alice. First, Alice’s public key must correspond to Alice’s address in the previous transaction, proving that the public key is valid — A bitcoin address can easily be derived from the public key. Next, Alice’s digital signature can be verified using Alice’s public key.
And that’s it for transactions for now! Hopefully that was a good introduction. There is so so much more to dive into such as more complex scripting, multi-signature transactions, Segwit.
Q: Do all transactions have to have inputs and outputs?
A: No. A transaction can contain zero inputs which are called Coinbase Transactions (not to be confused by the company named Coinbase). These transactions have outputs without needing any inputs to the transaction. Coinbase transactions are special transactions which are created miners and included as the first transaction in a block. They are what pays miners for their work.
Q: It seems like the UTXO model is quite complex and hard to manage. So why did Bitcoin implement the conventional account model where you can debit and credit account balances?
A: Advantages of the UTXO model:
- Higher degree of privacy: If a user uses a new address for each transaction that they receive then it can be difficult to link wallets to each other.
Disadvantages of the UTXO model:
- Need to save more data: A transaction can produce multiple UTXO, all of which need to be saved as separate entities rather than simply storing a debit and credit.
- Not simple: This model isn’t as easy to code and understand, especially once more complex scripts become involved. In fact, Ethereum implements the account model, to simplify writing smart contracts.