Bitcoin Transactions
Transaction Outputs and Inputs
Transaction Outputs
Every bitcoin transaction creates outputs, which are recorded on the bitcoin ledger. Almost all of these outputs, with one exception (see [op_return]) create spendable chunks of bitcoin called UTXO, which are then recognized by the whole network and available for the owner to spend in a future transaction.
UTXO are tracked by every full-node bitcoin client in the UTXO set. New transactions consume (spend) one or more of these outputs from the UTXO set.
Transaction outputs consist of two parts:
- An amount of bitcoin, denominated in satoshis, the smallest bitcoin unit
- A cryptographic puzzle that determines the conditions required to spend the output
The cryptographic puzzle is also known as a locking script, a witness script, or a scriptPubKey.
The transaction scripting language, used in the locking script mentioned previously, is discussed in detail in Transaction Scripts and Script Language.
Now, let's look at Alice's transaction (shown previously in Transactions - Behind the Scenes) and see if we can identify the outputs. In the JSON encoding, the outputs are in an array (list) named vout:
"vout": [ { "value": 0.01500000, "scriptPubKey": "OP_DUP OP_HASH160 ab68025513c3dbd2f7b92a94e0581f5d50f654e7 OP_EQUALVERIFY OP_CHECKSIG" }, { "value": 0.08450000, "scriptPubKey": "OP_DUP OP_HASH160 7f9b1a7fb68d60c536c2fd8aeaa53a8f3cc025a8 OP_EQUALVERIFY OP_CHECKSIG", } ]
As you can see, the transaction contains two outputs. Each output is defined by a value and a cryptographic puzzle. In the encoding shown by Bitcoin Core, the value is shown in bitcoin, but in the transaction itself it is recorded as an integer denominated in satoshis. The second part of each output is the cryptographic puzzle that sets the conditions for spending. Bitcoin Core shows this as scriptPubKey and shows us a human-readable representation of the script.
The topic of locking and unlocking UTXO will be discussed later, in Script Construction (Lock + Unlock). The scripting language that is used for the script in scriptPubKey is discussed in Transaction Scripts and Script Language. But before we delve into those topics, we need to understand the overall structure of transaction inputs and outputs.
Transaction serialization - outputs
When transactions are transmitted over the network or exchanged between applications, they are serialized. Serialization is the process of converting the internal representation of a data structure into a format that can be transmitted one byte at a time, also known as a byte stream. Serialization is most commonly used for encoding data structures for transmission over a network or for storage in a file. The serialization format of a transaction output is shown in Transaction output serialization.
Table 1. Transaction output serialization
Size | Field | Description |
---|---|---|
8 bytes (little-endian) |
Amount |
Bitcoin value in satoshis (10-8 bitcoin) |
1–9 bytes (VarInt) |
Locking-Script Size |
Locking-Script length in bytes, to follow |
Variable |
Locking-Script |
A script defining the conditions needed to spend the output |
Most bitcoin libraries and frameworks do not store transactions internally as byte-streams, as that would require complex parsing every time you needed to access a single field. For convenience and readability, bitcoin libraries store transactions internally in data structures (usually object-oriented structures).
The process of converting from the byte-stream representation of a transaction to a library's internal representation data structure is called deserialization or transaction parsing. The process of converting back to a byte-stream for transmission over the network, for hashing, or for storage on disk is called serialization. Most bitcoin libraries have built-in functions for transaction serialization and deserialization.
See if you can manually decode Alice's transaction from the serialized hexadecimal form, finding some of the elements we saw previously. The section containing the two outputs is highlighted in Alice's transaction, serialized, and presented in hexadecimal notation to help you:
0100000001186f9f998a5aa6f048e51dd8419a14d8a0f1a8a2836dd73 4d2804fe65fa35779000000008b483045022100884d142d86652a3f47 ba4746ec719bbfbd040a570b1deccbb6498c75c4ae24cb02204b9f039 ff08df09cbe9f6addac960298cad530a863ea8f53982c09db8f6e3813 01410484ecc0d46f1918b30928fa0e4ed99f16a0fb4fde0735e7ade84 16ab9fe423cc5412336376789d172787ec3457eee41c04f4938de5cc1 7b4a10fa336a8d752adfffffffff02 60e31600000000001976a914ab6 8025513c3dbd2f7b92a94e0581f5d50f654e788acd0ef800000000000 1976a9147f9b1a7fb68d60c536c2fd8aeaa53a8f3cc025a888ac 00000000
Here are some hints:
-
There are two outputs in the highlighted section, each serialized as shown in Transaction output serialization.
-
The value of 0.015 bitcoin is 1,500,000 satoshis. That's
16 e3 60
in hexadecimal. -
In the serialized transaction, the value
16 e3 60
is encoded in little-endian (least-significant-byte-first) byte order, so it looks like60 e3 16
. -
The scriptPubKey length is 25 bytes, which is 19 in hexadecimal.