With all things in place, we’re ready to examine what Bitcoin transactions are made of. All the loose ends about scripts will be tied up, plus you’ll practice some C code to accomplish our main mission, that is writing a raw transaction by hand.
Unfortunately, transactions and scripts are sort of a chicken and egg situation. Whatever subject you start from, you’ll definitely need a basic grasp of the other one to get things going. I chose to leave transactions last because I liked a bottom-up approach to this series, but I had to take some concepts for granted –like inputs and outputs– that are going to be clear in this final part.
Transaction data structures
This is what a transaction embeds:
- Some constant values.
- An array of one or more inputs.
- An array of one or more outputs.
Before writing raw transactions, I’m going to describe the data structures defined in tx.h. Needless to say, all number fields will be serialized little-endian.
Transaction outputs are the blockchain entities actually holding bitcoin value:
value field is the transferred bitcoin amount in satoshis, and the
script_len (varint) plus
script (byte array) fields are a vardata holding the output script code. The script contains the instructions to later redeem the output value. Within a transaction, each output has an index that is its offset in the outputs array.
Any Bitcoin transaction that is not coinbase (read next section), must refer to one or more previously mined transactions, because what transactions do is moving coins from some outputs to others. Well, an outpoint is a fixed structure that expresses a pointer to an existing transaction output:
txid field is the hash256 identifier of the referred transaction (little-endian), while
index is the 0-based offset of the output in the transaction outputs array.
A transaction input is an entity able to redeem value from a previously unspent output, also known as UTXO:
outpoint field is the pointer to the UTXO we want to spend. The
script_len (varint) plus
script (byte array) fields are a vardata holding the input script that, prepended to the UTXO script, is expected to succeed. The
sequence field is left for advanced operations, most of the time you’ll just set it to
Now that all subcomponents were described, here’s the layout of a blockchain transaction:
version of a transaction is established by network consensus and is currently constant
1. I won’t cover
locktime for now, just set it to zero. When serialized, the inputs and outputs arrays are prefixed with a varint announcing their count.
To make things clearer, I want to show you how to serialize a transaction in code. The
bbp_tx_serialize function is taken from tx.h:
flag parameter and assume it’s
0 to skip the last
if block. The code is pretty simple and I think it doesn’t need further explanations. If you’re in trouble, you might consider reading again the articles on blockchain serialization.
One last thing. The
bbp_tx_serialize function expects a properly allocated byte array, so you must use
bbp_tx_size to get the exact amount of bytes required to serialize the
tx transaction, for example:
Coinbase transactions (which inspired the Coinbase company name) are the only transactions without real inputs. They’re sort of genesis transactions, because they create bitcoins from nowhere and are not connected to any previous transaction. Each block in the blockchain has one and one only coinbase transaction that rewards the block miner with the famous ever-halving amount of bitcoins (currently 25 BTC).
Here’s an example coinbase transaction from Mainnet. It has a single output that sends a 25 BTC reward plus some fee to the following address:
by using a standard P2PKH output script:
OP_DUP OP_HASH160 [c8 25 a1 ec f2 a6 83 0c 44 01 62 0c 3a 16 f1 99 50 57 c2 ab] OP_EQUALVERIFY OP_CHECKSIG
The push data element is exactly the above address properly Base58Check-decoded. Likewise, the transaction has only one input. Since a coinbase transaction creates bitcoins, its input doesn’t point to any previous UTXO. Typically, coinbase input scripts are placeholders for block metadata, like the block height in the blockchain, the name of the mining software, generic binary data etc.
Next block in chain?
You learned the fundamental transaction data structures. Most transactions draw coins from previous outputs, while coinbase transactions generate coins from nowhere.
In the next article you’ll learn to build your first blockchain transaction. Please share this post if you enjoyed it and use the form below for questions and comments!