November 16, 2025

3. Blockchain and Bitcoin - Transactions Prove Ownership and Deliver Funds

Transactions Prove Ownership and Deliver Funds

Bitcoin does not track balances in the way a traditional bank account does. Instead, it uses a model based on unspent transaction outputs, usually called UTXOs. When people say that someone “has 5 BTC,” what they really mean is that this person controls a set of UTXOs whose total value is at least 5 BTC and which they can validly spend with their private key.

ref: How Bitcoin Records Which Coins You Spend: https://shiluqi.blogspot.com/2025/11/blockchain-and-bitcoin-records-coins.html (consider to read this first)


Balances as Spendable UTXOs

A UTXO is a specific transaction output that has not yet been spent by any later transaction. Each output has a few key pieces of data:

  • The amount of bitcoin.

  • A locking script that says who is allowed to spend it and under what conditions, most commonly “whoever can present a valid signature from the private key corresponding to this address.”

There is no global table that says “address X has Y BTC.” The network maintains a global set of all UTXOs. A “balance” is simply the sum of all UTXOs that a particular wallet can unlock. Wallet software builds this view for you; the consensus rules themselves only care about UTXOs and do not care about user balances.

When you create a transaction, you do not tell the network “send 5 BTC from address B.” Instead, you present a set of specific UTXOs as inputs. The network checks that:

  1. Each referenced UTXO really exists and has not already been spent.

  2. Your transaction includes valid unlocking data that proves you are allowed to spend those UTXOs.

  3. The total value of the inputs is at least the total value of the outputs plus any transaction fee.

If all of these checks pass, the transaction is accepted.


UTXOs example

Here’s a concrete, human-readable view of what a real Bitcoin transaction looks like, and how vout and the “addresses array” fit into it. A JSON-style example of the transaction: addr_B spends two UTXOs (3 BTC and 4 BTC) and sends 5 BTC to addr_A, 2 BTC back to itself as change, with no fee.

click to open example
{ "txid": "ff00ee11dd22cc33bb44aa5599887766554433221100ffeeddccbbaa99887766", "hash": "ff00ee11dd22cc33bb44aa5599887766554433221100ffeeddccbbaa99887766", "version": 1, "size": 225, "vsize": 144, "locktime": 0, "vin": [ { "txid": "1111111122222222333333334444444455555555666666667777777788888888", "vout": 0, "scriptSig": { "asm": "3045022100...signature_for_3BTC_input...01 03abcdef...pubkey_of_addr_B...", "hex": "483045022100...signature_hex...012103abcdef...pubkey_hex..." }, "sequence": 4294967295 }, { "txid": "99999999aaaabbbbccccddddeeeeffff00001111222233334444555566667777", "vout": 0, "scriptSig": { "asm": "3045022100...signature_for_4BTC_input...01 03abcdef...pubkey_of_addr_B...", "hex": "483045022100...signature_hex...012103abcdef...pubkey_hex..." }, "sequence": 4294967295 } ], "vout": [ { "value": 5.00000000, "n": 0, "scriptPubKey": { "asm": "OP_DUP OP_HASH160 76a91489abcdef0123456789abcdef0123456789abcd88ac OP_EQUALVERIFY OP_CHECKSIG", "hex": "76a91489abcdef0123456789abcdef0123456789abcd88ac", "type": "pubkeyhash", "addresses": [ "1BitcoinAddressForReceiver..." ] } }, { "value": 2.00000000, "n": 1, "scriptPubKey": { "asm": "OP_DUP OP_HASH160 76a914fedcba9876543210fedcba9876543210fedcba9888ac OP_EQUALVERIFY OP_CHECKSIG", "hex": "76a914fedcba9876543210fedcba9876543210fedcba9888ac", "type": "pubkeyhash", "addresses": [ "1BitcoinAddressForSenderChange..." ] } } ] }

Key points:

  • vin[0] and vin[1] spend the two UTXOs owned by addr_B (3 BTC and 4 BTC).
    vout[0] is a 5 BTC payment to addr_A (addresses: ["1BitcoinAddressForReceiver..."]).
    vout[1] is a 2 BTC change output back to addr_B (addresses: ["1BitcoinAddressForSenderChange..."]).
    Each vout has a scriptPubKey, and block explorers parse that script to produce an addresses array; it is an array so that things like multisig outputs can list multiple addresses.

1. Conceptual shape of a Bitcoin transaction

A normal (non-coinbase) Bitcoin transaction has four main part. You can think of it like this:

Transaction

Version: integer
Inputs: list of Input
Outputs: list of Output
Locktime: integer

Each input spends one old UTXO. Each output creates one new UTXO.

A single input looks like: Input

Previous transaction id (txid)
Previous output index (vout index)
Unlocking script (scriptSig or witness)
Sequence

A single output (one element of vout) looks like: Output

Value (in satoshis)
Locking script (scriptPubKey)

2. What multiple vout entries represent

When you see “vout array”, it simply means “this transaction has several outputs”.
Each element in the array is one new UTXO.

For example, a typical payment:

  • Input 0: spends some old UTXO owned by the sender.
    Prev txid: 1a2b3c...
    Prev index: 0
    Unlocking script: [signature, public key of sender]
    Sequence: 0xffffffff

  • Output 0: payment to the receiver.
    Value: 0.05000000 BTC
    Locking script: OP_DUP OP_HASH160 <hash(receiver_pubkey)> OP_EQUALVERIFY OP_CHECKSIG

  • Output 1: change back to the sender.
    Value: 0.14900000 BTC
    Locking script: OP_DUP OP_HASH160 <hash(sender_pubkey)> OP_EQUALVERIFY OP_CHECKSIG  

Here:

  • vout[0] is “pay 0.05 BTC to the receiver”
    vout[1] is “pay 0.149 BTC back to myself as change”

Each of these outputs becomes a separate UTXO, identified by (txid_of_this_tx, index_in_vout).

So:

  • More recipients → more entries in vout.

  • Change back to the sender → another entry in vout.

  • Special outputs like OP_RETURN data → again another element in vout.

3. Why a “addresses” array inside each vout?

On chain, an output only has:

  • a numeric value

  • a locking script (scriptPubKey)

There is no native “addresses” field in the protocol.

Block explorers and some APIs parse scriptPubKey and try to interpret it. To make it generic, they often expose something like:

  • type: e.g. “pubkeyhash”, “scripthash”, “witness_v0_keyhash”, “multisig”

  • addresses: a list of human addresses involved (if they can be deduced)

This is an array because:

  1. Multisig scripts can involve several public keys, which correspond to several addresses.
    For example: “2 of 3 multisig between A, B, C”. An explorer might show
    addresses = [addr_A, addr_B, addr_C] for that one output.

  2. Some complex or custom scripts may not map cleanly to a single address. The API stays general by always using “list of addresses” even when there is only one.

In the simplest and most common case (standard pay-to-public-key-hash), there is effectively one address per output. The addresses array just holds that single element.

So conceptually:

Output
Value: 0.05000000 BTC
scriptPubKey: OP_DUP OP_HASH160 <20-byte hash> OP_EQUALVERIFY OP_CHECKSIG

Explorer representation, roughly:

type: “pubkeyhash”
addresses: [receiver_address]

The array is a convenience of the API, not a requirement of the Bitcoin protocol.

4. Abstract meaning of each major field

If we describe the transaction abstractly:

Transaction
Version: how to interpret some fields (and for future upgrades)

Inputs: each one says
“I am destroying this old UTXO (given by txid and index),
and here is the proof (unlocking script) that I am allowed to do that”

Outputs: each one says
“I am creating a new UTXO with this value,
and here is the condition (locking script) that must be satisfied to spend it later”

Locktime: the earliest time or block height when this transaction becomes valid,
or zero for “valid immediately”

The UTXO set is just “the set of all outputs from all transactions which have not yet been referenced by any later input”.

5. Example of a serialized byte stream (hex), roughly

Here is a small, simplified example of how the serialized bytes might look.
This is not a full real transaction, just enough to give you a feeling.

click to open
01000000 01 e2b3a4f18c9d...3f2c1b0a9f876543210fedcba9876543210ffeedccbbaa9988 00000000 19 76a91489abcdef0123456789abcdef0123456789abcd88ac ffffffff 02 00f2052a01000000 19 76a9140123456789abcdef0123456789abcdef01234588ac 8096980000000000 19 76a914fedcba9876543210fedcba9876543210fedcba9888ac 00000000

Very briefly:

  • 01000000
    Version = 1 (little endian)

  • 01
    Number of inputs = 1

  • e2b3a4...
    Previous txid (32 bytes, little endian)

  • 00000000
    Previous output index = 0

  • 19
    Length of scriptSig = 0x19 bytes

  • 76a9...88ac
    scriptSig bytes (simplified)

  • ffffffff
    Sequence

  • 02
    Number of outputs = 2

  • 00f2052a01000000
    First output value (8 bytes, little endian, for example 5 BTC)

  • 19
    Length of first scriptPubKey

  • 76a914...88ac
    First scriptPubKey (pay to hash of receiver)

  • 8096980000000000
    Second output value (for example change)

  • 19
    Length of second scriptPubKey

  • 76a914...88ac
    Second scriptPubKey (pay to hash of sender/change address)

  • 00000000
    Locktime

In reality, scriptSig and witness fields are more complex, but this illustrates the idea: the transaction is just a sequence of bytes, with counts and lengths, that encode exactly the structure we described earlier.



An Example of Selecting Coins to Spend

Consider a very small “ledger” with a few transactions:

  • (tx1, 0): 3 BTC to addr_B
    (tx2, 0): 10 BTC to addr_C
    (tx3, 0): 4 BTC to addr_B
    (tx3, 1): 1 BTC to addr_A

Assume that none of these outputs has been spent yet. The current UTXO set contains:

  • (tx1, 0) = 3 BTC owned by addr_B
    (tx2, 0) = 10 BTC owned by addr_C
    (tx3, 0) = 4 BTC owned by addr_B
    (tx3, 1) = 1 BTC owned by addr_A

From the perspective of addr_B, the wallet sees two UTXOs:

  • 3 BTC from (tx1, 0)
    4 BTC from (tx3, 0)

Addr_B therefore controls 7 BTC in total.

Now suppose addr_B wants to send 5 BTC to addr_A, and for simplicity we ignore transaction fees. The wallet must choose which UTXOs to spend. One simple strategy is to use both UTXOs belonging to addr_B:

  • Inputs: (tx1, 0) and (tx3, 0), totaling 7 BTC.

  • Outputs:

    • 5 BTC to addr_A.

    • 2 BTC back to addr_B as change.

The new transaction contains two inputs that refer to (tx1, 0) and (tx3, 0), along with signatures that prove addr_B has the right to spend them. It also contains two outputs, one to addr_A and one to a change address controlled by addr_B. The inputs sum to 7 BTC, the outputs sum to 7 BTC, so the transaction balances.

The important part is that the transaction itself explicitly says which old outputs are being spent, by including a pair (txid, index) for each input. The network does not “search for 5 BTC for addr_B.” It simply verifies that the specific outputs you referenced are real, unspent, and properly authorized.


Why (txid, index) Matters and Who Remembers It

Every transaction output is uniquely identified by the transaction it appears in, plus its position within that transaction. This pair is often called an outpoint and looks like: (txid, index)

The consensus rules require that when you spend a UTXO, you must specify exactly which outpoint you are spending through these two values. When your transaction is received, a validating node:

  1. Looks up each outpoint in its UTXO set.

  2. Checks that it still exists and has not been spent.

  3. Uses the attached unlocking data to verify that you are authorized.

Your wallet software keeps track of which UTXOs you own and knows their (txid, index) pairs. When constructing a transaction, the wallet picks suitable UTXOs and fills in those technical details for you.

If you ever restore a wallet from a seed phrase, the software can recompute all your addresses, then scan the blockchain from the beginning and reconstruct the list of UTXOs that belong to you. In this way it can rebuild the set of outpoints you control without you manually tracking anything.


How Wallets Find the UTXOs That Belong to You

From the consensus point of view, the “primary key” is the outpoint (txid, index). The amount and the locking script are just attributes associated with that key. The network does not maintain any global index mapping “addr_B → all UTXOs.” It only needs to efficiently look up a UTXO when given its outpoint.

Wallets, however, do need to know which UTXOs belong to you. They achieve this by combining two pieces of information:

  1. A list of addresses or scripts that belong to the wallet. These can be derived from a seed phrase through a hierarchical deterministic scheme, giving the wallet a large but predictable set of addresses it controls.

  2. A view of the blockchain and the mempool that contains all transactions seen so far.

A full node wallet downloads every block and maintains a complete local database of UTXOs and transactions. It can then scan through all outputs and mark those whose locking scripts match one of the wallet’s addresses. A lightweight wallet usually does not download the entire chain; instead it queries servers or uses compact filters to discover relevant transactions. Either way, the wallet builds its own local mapping from “my addresses” to “my UTXOs,” even though the protocol does not require any such mapping to exist globally.


Inputs, Outputs and Scripts Inside a Transaction

Apart from special coinbase transactions that create new coins as block rewards, most Bitcoin transactions follow the same structural pattern.

Each output describes a new UTXO. It contains:

  • A value in bitcoin.

  • A locking script (often called scriptPubKey) which describes the spending condition. The most common form is “pay to public key hash,” which says that the spender must present a public key whose hash matches a given value and a valid signature made with the corresponding private key.

Each input describes the spending of an existing UTXO. It contains:

  • The outpoint, that is the previous transaction id and output index.

  • Unlocking data (scriptSig and, for modern transactions, witness data) which is usually:

    • A full public key.

    • A digital signature over the new transaction, produced with the private key corresponding to that public key.

To verify an input, a node retrieves the referenced UTXO from the UTXO set, extracts its locking script, and then combines that locking script with the unlocking data from the input. It runs this combined script in a simple stack based virtual machine. For a typical pay to public key hash output, the checks include:

  1. Hash the public key provided in the input and compare it to the public key hash stored in the old output.

  2. Use the public key to verify that the signature in the input is valid for this transaction.

If the script executes successfully for every input and the total amounts make sense, the transaction is valid.


Private Keys, Public Keys and Addresses

The relationship between private keys, public keys and addresses is central to how ownership works in Bitcoin.

  1. A private key is a 256-bit number selected from a very large allowed range. Wallets typically generate it using a cryptographically secure random process, and it must be kept secret and never published to the network.

  2. A public key is derived from the private key using elliptic curve multiplication. It is safe to share with the world.

  3. An address is usually a human friendly encoding of a hash of the public key. For example, the public key is hashed with SHA256 and RIPEMD160, and then some metadata and checksum are added and encoded. The blockchain generally stores this hash instead of the raw public key, at least until the coins are spent.

This design means that when you first receive coins, the output normally contains only a hash of your public key, not the public key itself. The full public key is revealed later when you spend that output.


Where the Public Key Actually Appears

When someone pays you, the transaction output that pays to your address contains a locking script that includes the hash of your public key. At that point, the network sees only that hash and not your full public key.

When you spend those coins, you must create an input that points to that output and that includes your public key and a valid signature. Nodes then:

  1. Hash your public key and compare it with the hash stored in the old output.

  2. If they match, use your public key to verify the signature on your new transaction.

There is no separate database of public keys. Your public key is carried in the input of the transaction where you spend funds. Earlier, when you only received those funds, the chain stored only a hash of that key inside the locking script. This is why a node can verify your signature: you supply the public key at the time of spending, and the node checks that it corresponds to the hash that was recorded when you were paid.


Signatures Rather Than Encryption

The cryptography used in Bitcoin transactions is about digital signatures, not about encrypting and decrypting data. Nothing on the chain is hidden by encryption; all transaction data is public.

The important operations are:

  • Your wallet constructs the transaction in a specific format and then signs the relevant parts of it with your private key using the ECDSA algorithm.

  • The resulting signature is broadcast along with the transaction and is visible to everyone.

  • Any node can use the public key included in the input to check whether that signature is valid for this transaction.

The private key never leaves your wallet and is never uploaded to the network. The public key and the signature are enough for everyone else to verify that you authorized the transaction. This is how the system proves control over coins without revealing any secret keys.


How Recipients Discover Incoming Payments

Once you broadcast a transaction, it is propagated across the network and typically placed into mempools on many nodes. Miners may then include it in a block, at which point it becomes part of the canonical blockchain and begins accumulating confirmations as more blocks are added on top.

The blockchain itself does not know human identities. It only records that a particular output has a certain amount and a certain locking script. To turn this into the user experience of “I received 5 BTC,” a wallet has to do some work.

A wallet knows its own addresses because they are derived from its seed or collection of private keys. It then monitors blockchain data and mempool data to find any output whose locking script matches one of its addresses. Whenever it finds such an output, it treats it as incoming funds.

A full node wallet does this by scanning every new transaction and block locally. A lightweight wallet, especially on a mobile device, typically queries remote servers or uses block filters. Either way, the logic is similar:

  1. Maintain the list of addresses or script patterns that the wallet can spend from.

  2. Receive information about new transactions and blocks from the network.

  3. For each transaction, inspect the outputs to see whether any locking script matches one of the wallet’s own addresses.

  4. If a match is found, record that UTXO as owned and show it in the user interface, first as unconfirmed when it is only in the mempool, and then as confirmed once it appears in a block.

If the recipient’s wallet is offline when the payment is made, the transaction still reaches the network and can be included in blocks. Later, when the wallet comes online again, it synchronizes from the last block height it knows, scans through all newer blocks, and discovers any outputs that pay to its addresses. In this way it retroactively learns about any payments that arrived while it was offline.


How to Quickly Find a Transaction

In Bitcoin, every transaction has a unique transaction id (txid), which is a hash of the transaction’s contents and acts like its fingerprint. The fastest way to locate a transaction among all transactions in the world is to search by this txid. Full nodes store blocks and transactions in indexed data structures, similar to how a database stores rows with primary keys, so a lookup by txid is basically a direct index lookup, not a slow scan from the genesis block. Block explorers expose this through a “search by txid” field, and wallet software usually remembers the txid of any transaction you send or receive. When you click on a transaction in your wallet, it simply uses that txid to query a node or a block explorer for the full details.


How a Spent Transaction Output Is Marked as Used

Bitcoin does not actually mark an entire transaction as “invalid” or “expired” after you send your BTC to someone else. Transactions that are confirmed remain part of the permanent history. What changes is the status of the outputs from that transaction. Each output is a UTXO until it is spent by a later transaction. When you send BTC, your new transaction references an old output by its (txid, output_index). Once this new transaction is validated and included in a block, every node removes the referenced outputs from its UTXO set, effectively marking them as spent. The original transaction is still valid and visible on the chain, but its outputs are no longer available to be spent again. If anyone later tries to create another transaction that spends the same output, nodes will see that this outpoint is not in the UTXO set anymore and will reject the new transaction as a double spend.


Putting the Pieces Together

A Bitcoin “balance” is a set of unspent outputs that your wallet can unlock. When you send funds, your wallet chooses specific UTXOs, references them by their (txid, index) identifiers in the transaction inputs, and provides public keys and signatures that prove you control the corresponding private keys. Nodes verify that these outputs exist, are unspent, and are correctly authorized, and that the total input value covers the outputs and any fee.

The network itself only sees UTXOs and scripts, not user accounts. Wallets bridge the gap by tracking which addresses they control, scanning the blockchain for outputs that pay to those addresses, and presenting totals as balances. When someone pays you, your wallet automatically finds the transaction by watching for outputs that match your addresses, even if the payment occurred while the wallet was offline.

This combination of UTXO tracking, digital signatures, and local wallet logic is what allows Bitcoin to prove ownership of coins and to deliver payments across a global, public ledger without any central authority.

Other links: 

1. Blockchain and Bitcoin - Overview and Big Picture
https://shiluqi.blogspot.com/2025/11/blockchain-and-bitcoin-main-article.html

2. Blockchain and Bitcoin - How Bitcoin Records Which Coins You Spend

3. Blockchain and Bitcoin - Transactions Prove Ownership and Deliver Funds
this article

4. Blockchain and Bitcoin - Wallets, Keys, and Seed Phrases

5. Blockchain and Bitcoin - Fees, Mempools, and the Bitcoin Fee Market
TODO

6. Blockchain and Bitcoin - Bitcoin Scripts and Advanced Spending Conditions
TODO

7. Blockchain and Bitcoin - Privacy and a First Look at On-chain Analysis
TODO

No comments:

Post a Comment