Transaction

Unlocking and locking batches of bitcoins

Diagram of the structure of a bitcoin transaction showing the inputs and outputs.

A bitcoin transaction is just a bunch of data that unlocks and locks up batches of bitcoins.

To be more precise, a transaction:

  1. Selects existing batches of bitcoins (inputs) and unlocks them.
  2. Creates new batches of bitcoins (outputs) and puts new locks on them.

You can have multiple inputs and outputs in a single transaction.

So you can think of a transaction as being part of a chain of outputs; one transaction creates an output, and then a future transaction selects that output (as an input) and unlocks it to create new outputs.

Diagram showing a chain of transactions where the new transactions spend the outputs of previous transactions.

The locking and unlocking mechanism involves some cryptography. The lock on an output usually contains a public key, and if you want to unlock it, you'll need the corresponding private key for that public key to create a digital signature for it.

Diagram showing a public key being placed on the output of a transaction. Diagram showing a private key being used to create a digital signature to unlock the input of a transaction.
A digital coin contains the public key of its owner. To transfer it, the owner signs the coin together with the public key of the next owner. Anyone can check the signatures to verify the change of ownership.
Satoshi Nakamoto, p2pfoundation.ning.com

This cryptography was not invented by Bitcoin; digital signature systems already existed, and Bitcoin utilizes one so that people can "own" and send each other quantities of bitcoin.

But whilst that's interesting, we don't need to know about this underlying cryptography if we just want to be able to understand the structure of bitcoin transactions and how they work, which is what this page is all about.

Structure

What does a raw bitcoin transaction look like?

A raw bitcoin transaction is made up of fields, each containing bytes of data.

All bitcoin transactions have the same basic structure, so to decode them you just need to know the size of each field and what format the data is in.

tool-66208b48e1eff
Tool Icon

Transaction Splitter

Split a raw transaction in to individual fields.

Result

 
0 secs
Transaction
Field Example Size Format Description
Version 02000000 4 bytes Little-Endian The version number for the transaction. Used to enable new features.
Marker 00 1 byte   Used to indicate a segwit transaction. Must be 00.
Flag 01 1 byte   Used to indicate a segwit transaction. Must be 01 or greater.
Input Count 01 variable Compact Size Indicates the number of inputs.
Input(s)
Field Example Size Format Description
TXID [TXID] 32 bytes Natural Byte Order The TXID of the transaction containing the output you want to spend.
VOUT 01000000 4 bytes Little-Endian The index number of the output you want to spend.
ScriptSig Size 6b variable Compact Size The size in bytes of the upcoming ScriptSig.
ScriptSig [script] variable Script The unlocking code for the output you want to spend.
Sequence fdffffff 4 bytes Little-Endian Set whether the transaction can be replaced or when it can be mined.

This structure repeats for every input.

Output Count 02 variable Compact Size Indicates the number of outputs.
Output(s)
Field Example Size Format Description
Amount e99e060000000000 8 bytes Little-Endian The value of the output in satoshis.
ScriptPubKey Size 19 variable Compact Size The size in bytes of the upcoming ScriptPubKey.
ScriptPubKey [script] variable Script The locking code for this output.

This structure repeats for every output.

Witness
Field Example Size Format Description
Stack Items 02 variable Compact Size The number of items to be pushed on to the stack as part of the unlocking code.
Field Example Size Format Description
Size 47 variable Compact Size The size of the upcoming stack item.
Item 304...b01 variable Bytes The data to be pushed on to the stack.

This structure repeats for every stack item.

This structure repeats for every input.

Locktime 00000000 4 bytes Little-Endian Set a time or height after which the transaction can be mined.

Note: Rows in highlighted in blue are fields used in segwit transactions.

Version

Little-Endian

The version field allows you to enable new transaction features.

A basic transaction has version number of 1, but most modern bitcoin transactions now use a version number of 2.

Marker & Flag (Optional)

These next two bytes can be used to indicate a segregated witness transaction.

These bytes are only required if you're unlocking inputs that have a P2WPKH, P2WSH, or P2TR lock on them (i.e. they require use of the witness field at the end of the transaction).

Marker

Set this to 00 to indicate that this is a segregated witness transaction. This must always be 00.

Flag

Set this to 01 for a segregated witness transaction. In the future this byte may be incremented to indicate newer transaction structures.

Older Bitcoin software that hasn't upgraded to use segregated witness transactions will interpret these marker and flag bytes as indicating that the transaction has 0 inputs and 1 output, which would make the transaction invalid. However, old nodes wouldn't actually be sent these bytes when they are sent the transaction.

Input Count

Compact Size

The input count field indicates the upcoming number of inputs in the transaction.

Input(s)

Diagram of the structure of a transaction input.

Each input in a transaction has its own inner structure. But all you're basically doing is selecting an output from a previous transaction and providing the unlocking code for it.

For each input you just need to repeat the following set of fields:

TXID

TXID
Diagram showing how an input is selected by referencing the TXID and VOUT from a previous transaction.

This is the TXID for the transaction that created the output you want to spend.

The TXID you use to reference a previous transaction in raw transaction data is in natural byte order, which is actually the reverse order of bytes you see on blockchain explorers. This is just a quirk of bitcoin.

A TXID is created by hashing the transaction data. Every transaction has its own unique TXID.

VOUT

Little-Endian

This is the index number for the output in the transaction you have just referenced.

A transaction can create multiple outputs, so you need to specify which output from the transaction you want to spend. This combination of a TXID:VOUT is referred to as an outpoint, which makes for a unique identifier for each individual batch of bitcoins inside the blockchain.

The output you want to spend must not have been spent in a previous transaction.

The first output of a transaction is at index number 0.

VOUT is short for "Vector Output". A "vector" is basically a programming term for a numbered list of items. It's a structure commonly used in C++, which is the language Bitcoin was originally programmed in.

ScriptSig Size

Compact Size

Indicates the upcoming size of the unlocking code for this input.

The unlocking code can vary in length depending on the type of lock used, so that's why we need to specify how long the upcoming unlocking code is going to be so we know how much data we need to read.

ScriptSig (Optional/Legacy)

The scriptsig field contains the unlocking code for the output you have just referenced. Every output has some form of lock on it, so you need to provide some data that will satisfy the conditions of the lock.

This field uses Script, and it typically contains a digital signature. This signature is created by signing the current transaction data using the private key that created the public key inside the lock.

This field is now only used for unlocking outputs with legacy locking scripts. These are:

Sequence

Sequence

The sequence field allows you to enable some additional features for the input you're spending:

  1. Locktime. By setting at least one of the sequences to 0xFFFFFFFE or below you enable the upcoming locktime field for the entire transaction.
  2. Replace-by-Fee. By setting a sequence value of 0xFFFFFFFD or below you enable this input to be spent in a different transaction with a higher fee (if this current transaction is still in the memory pool at the time).
  3. Relative Locktime. By setting a sequence value of less than 0x80000000 you can set a relative locktime on this input. This means the transaction cannot be mined until a specific point in time. This can either be a number of seconds or a number of blocks from when the output you've referenced was originally mined.

This field has been repurposed a number of times since it's original design, which is why it's a mixture of different features all in one.

A popular setting is 0xFFFFFFFD, as this enables both the locktime and replace-by-fee features, which are generally useful in most transactions.

Output Count

Compact Size

The output count field indicates the upcoming number of outputs.

Output(s)

Diagram of the structure of a transaction output.

Each output creates a new batch of bitcoins with their own lock on them. I call them "batches" of bitcoins, but the technical term is output.

Just like an input, an output has its own inner structure. For each output you just need to repeat the following set of fields:

Amount

Little-Endian
Unit Converter
Diagram of the amount field of a transaction output.

The amount field is where you set the value of the output in satoshis (1 satoshi = 0.00000001 BTC).

This field is 8 bytes in size, which means that you can put up to 0xFFFFFFFFFFFFFFFF or 18446744073709551615 satoshis in to one output. This is the equivalent of 184,467,440,737.09551615 BTC, which is more BTC than is in existence.

The total value of your outputs cannot exceed the total value of your inputs.

Any remaining amount of bitcoin that isn't used up will be claimed by a miner as the transaction fee.

ScriptPubKey Size

Compact Size

Indicates the upcoming size of the locking code for this output.

You can put different types of locks on your output, so that's why we need to specify how long the upcoming locking code is going to be so we know how much data we need to read.

ScriptPubKey

Script
Diagram of the scriptPubKey field of a transaction output.

This is the actual locking code that we're placing on the output.

There are a number of different locking code patterns you can use. Here are the most common examples:

The legacy locking code uses actual fully-fledged Script language. However, the newer locking code for P2WPKH and P2WSH locks just uses a fixed structure.

It's called a "scriptpubkey" because it's a Script that usually contains a public key. That's not always the case, but that's what this field is commonly called anyway.

Witness (Optional)

Diagram showing the location of the witness field in a segwit transaction and how it's used to unlock inputs.

The witness is the area for unlocking code when you're unlocking inputs with P2WPKH, P2WSH, or P2TR locking scripts. You can think of it as being the new location for the ScriptSig fields in segwit transactions. The main difference is that it doesn't use any opcodes, as it's just a bunch of data pushes.

For example, to unlock a typical P2WPKH locking script you would use the following witness field:

The witness field for each input starts with a stack items field indicating the number of items in the witness field, followed by the size of each item and the actual item itself. Using the example above:

This repeats for every input in the transaction.

So as you can see it's more basic than using Script. However, even though it looks fairly similar and typically contains the same kind of data (e.g. public keys and signatures), witness data is not Script.

Locktime

Little-Endian
Unix Time

The locktime field allows you to specify a block height or time at which this transaction can be mined.

A transaction with a locktime set in the future cannot be mined in to a block, nor will it be accepted in to the mempools of nodes on the network. So if you create a transaction with a locktime in the future, you can share it with other people, but you will not be able to successfully submit it in to the network until the specific time or block height has been surpassed.

In other words, adding a locktime to a transaction is like post-dating a check.

At least one of the sequence fields must be set to 0xFFFFFFE or below for locktime to be enabled. If all of the sequences are at their maximum of 0xFFFFFFFF then the transaction is considered "final" and the locktime feature is disabled.

Gif

Here's a terrible gif I made in 2015 that shows what each field in raw transaction data is doing (in a legacy transaction):

Animated gif showing what each field in a raw transaction does.

Examples

Here are a few typical examples of actual raw transactions. It's probably more useful to inspect them on the explorer, but I've included them here anyway as they make for good examples of the general structure of transactions.

For more complex and interesting examples, check out the transaction page on the explorer.

1. Basic Legacy Transaction

010000000110ddd830599b17cc690535f7df28a84466eaca3c22f0d55b79023b6570f4fbc5010000008b483045022100e6186d6f344ce4df46b2e15d87093d34edbf5b50462b6b45f9bd499a6a62fbc4022055f56a1c4a24ea6be61564593c4196b47478a25cf596c1baf59f5a9a229b637c014104a41e997b6656bc4f5dd1f9b9df3b4884cbec254d3b71d928587695b0df0a80417432f4ca6276bc620b1f04308e82e70015a40f597d8260912f801e4b62ab089effffffff0200e9c829010000001976a9146f34d3811aded1df870359f311c2a11a015e945388ac00e40b54020000001976a91470d6734de69c1ac8913892f2df9be0e738d26c2d88ac00000000
{
  "version": "01000000",
  "inputcount": "01",
  "inputs": [
    {
      "txid": "10ddd830599b17cc690535f7df28a84466eaca3c22f0d55b79023b6570f4fbc5",
      "vout": "01000000",
      "scriptsigsize": "8b",
      "scriptsig": "483045022100e6186d6f344ce4df46b2e15d87093d34edbf5b50462b6b45f9bd499a6a62fbc4022055f56a1c4a24ea6be61564593c4196b47478a25cf596c1baf59f5a9a229b637c014104a41e997b6656bc4f5dd1f9b9df3b4884cbec254d3b71d928587695b0df0a80417432f4ca6276bc620b1f04308e82e70015a40f597d8260912f801e4b62ab089e",
      "sequence": "ffffffff"
    }
  ],
  "outputcount": "02",
  "outputs": [
    {
      "amount": "00e9c82901000000",
      "scriptpubkeysize": "19",
      "scriptpubkey": "76a9146f34d3811aded1df870359f311c2a11a015e945388ac"
    },
    {
      "amount": "00e40b5402000000",
      "scriptpubkeysize": "19",
      "scriptpubkey": "76a91470d6734de69c1ac8913892f2df9be0e738d26c2d88ac"
    }
  ],
  "locktime": "00000000"
}

Transaction: 251490baffd0d3d5175b77bf334ba866c4fd416fcc686a1001e188fba83b4ccb

This is a typical legacy transaction. It selects a single input with a P2PKH lock on it, and creates two new outputs with new P2PKH locks on them.

The input is unlocked by putting the original public key and signature in the ScriptSig field for that input.

Signatures are large and make up a significant portion of the total transaction size.

The second output is typically used for sending "change" back to an address that you own. This happens when the amount of satoshis in the input is greater than the amount you want to send.

2. Basic Segwit Transaction

010000000001013c735f81c1a0115af2e735554fb271ace18c32a3faf443f9db40cb9a11ca63110000000000ffffffff02b113030000000000160014689a681c462536ad7d735b497511e527e9f59245cf120000000000001600148859f1e9ef3ba438e2ec317f8524ed41f8f06c6a024730440220424772d4ad659960d4f1b541fd853f7da62e8cf505c2f16585dc7c8cf643fe9a02207fbc63b9cf317fc41402b2e7f6fdc1b01f1b43c5456cf9b547fe9645a16dcb150121032533cb19cf37842556dd2168b1c7b6f3a70cff25a6ff4d4b76f2889d2c88a3f200000000
{
  "version": "01000000",
  "marker": "00",
  "flag": "01",
  "inputcount": "01",
  "inputs": [
    {
      "txid": "3c735f81c1a0115af2e735554fb271ace18c32a3faf443f9db40cb9a11ca6311",
      "vout": "00000000",
      "scriptsigsize": "00",
      "scriptsig": "",
      "sequence": "ffffffff"
    }
  ],
  "outputcount": "02",
  "outputs": [
    {
      "amount": "b113030000000000",
      "scriptpubkeysize": "16",
      "scriptpubkey": "0014689a681c462536ad7d735b497511e527e9f59245"
    },
    {
      "amount": "cf12000000000000",
      "scriptpubkeysize": "16",
      "scriptpubkey": "00148859f1e9ef3ba438e2ec317f8524ed41f8f06c6a"
    }
  ],
  "witness": [
    {
      "stackitems": "02"
      "0": {
        "size": "47",
        "item": "30440220424772d4ad659960d4f1b541fd853f7da62e8cf505c2f16585dc7c8cf643fe9a02207fbc63b9cf317fc41402b2e7f6fdc1b01f1b43c5456cf9b547fe9645a16dcb1501"
      },
      "1": {
        "size": "21",
        "item": "032533cb19cf37842556dd2168b1c7b6f3a70cff25a6ff4d4b76f2889d2c88a3f2"
      },
    }
  ],
  "locktime": "00000000"
}

Transaction: f8c24461e0a08ede06539433affaba93e303ca9929c300cfc00a8929e8025a80

This is a typical segwit transaction. The presence of the 0001 marker+flag bytes indicates that it's a segwit transaction and that it makes use of a witness section.

It selects a single input with a P2WPKH lock on it, and creates two new outputs with new P2WPKH locks on them.

This transaction is functionally the same as the one above. It just uses a witness field for unlocking the input rather than the legacy ScriptSig field.

What makes this a "segwit" transaction is the fact that it spends a P2WPKH output from a previous transaction.

3. Transaction with both Legacy and Segwit Inputs

01000000000102f11271713fb911ebdb7daa111470853084c5b4f6ad73582517a73b1131839d71000000006a473044022001187384d8b30020a0ad6976805f0676da8e5fd219ffec084f7c22d2acd4838f0220074e3195a6e624b7ac5cb8e072d77f3b6363968040fc99f268affd4c08e11ac7012103510f10304c99bd53af8b3e47b3e282a75a50dad6f459c4c985898fd800a9e9a8fffffffff11271713fb911ebdb7daa111470853084c5b4f6ad73582517a73b1131839d710100000000ffffffff021027000000000000160014858e1f88ff6f383f45a75088e15a095f20fc663f2c1a0000000000001976a9142241a6c3d4cc3367efaa88b58d24748caef79a7288ac0002473044022035345342616cb5d6eefbbffc1de179ee514587dd15efe5ca892602f50336e30502207864061776e39992f317aee92dcc9595cc754b8f13957441d5ccd9ebd1b5cc0c0121022ed6c7d33a59cc16d37ad9ba54230696bd5424b8931c2a68ce76b0dbbc222f6500000000
{
  "version": "01000000",
  "marker": "00",
  "flag": "01",
  "inputcount": "02",
  "inputs": [
    {
      "txid": "f11271713fb911ebdb7daa111470853084c5b4f6ad73582517a73b1131839d71",
      "vout": "00000000",
      "scriptsigsize": "6a",
      "scriptsig": "473044022001187384d8b30020a0ad6976805f0676da8e5fd219ffec084f7c22d2acd4838f0220074e3195a6e624b7ac5cb8e072d77f3b6363968040fc99f268affd4c08e11ac7012103510f10304c99bd53af8b3e47b3e282a75a50dad6f459c4c985898fd800a9e9a8",
      "sequence": "ffffffff"
    },
    {
      "txid": "f11271713fb911ebdb7daa111470853084c5b4f6ad73582517a73b1131839d71",
      "vout": "01000000",
      "scriptsigsize": "00",
      "scriptsig": "",
      "sequence": "ffffffff"
    }
  ],
  "outputcount": "02",
  "outputs": [
    {
      "amount": "1027000000000000",
      "scriptpubkeysize": "16",
      "scriptpubkey": "0014858e1f88ff6f383f45a75088e15a095f20fc663f"
    },
    {
      "amount": "2c1a000000000000",
      "scriptpubkeysize": "19",
      "scriptpubkey": "76a9142241a6c3d4cc3367efaa88b58d24748caef79a7288ac"
    }
  ],
  "witness": [
    {
      "stackitems": "00"
    },
    {
      "stackitems": "02"
      "0": {
        "size": "47",
        "item": "3044022035345342616cb5d6eefbbffc1de179ee514587dd15efe5ca892602f50336e30502207864061776e39992f317aee92dcc9595cc754b8f13957441d5ccd9ebd1b5cc0c01"
      },
      "1": {
        "size": "21",
        "item": "022ed6c7d33a59cc16d37ad9ba54230696bd5424b8931c2a68ce76b0dbbc222f65"
      },
    }
  ],
  "locktime": "00000000"
}

Transaction: 846c308dc8ba79e9fc21985b1c10563d72ddff4a0ffb0e9c01d7db51fb7829ce

This is a slightly more complex transaction. It selects two inputs:

  1. The first input has a legacy P2PKH lock on it
  2. The second input has a P2WPKH lock on it

It then creates two new outputs:

  1. The first has a legacy P2PKH lock on it
  2. The second hash a P2WPKH lock on it

As a result, the first input makes use of the ScriptSig field, and the second makes use of the witness field.

Every input in a segwit transaction needs to have its own witness field. If the input doesn't need to make use of it, just set its witness field to 00 (i.e. zero stack items).

TXID

Diagram showing how a TXID is constructed from raw transaction data (not including witness data).
TXID

Every transaction has its own unique reference number. This known as a Transaction ID (TXID).

A TXID is created by double-SHA256ing of the following fields in the raw transaction data:

TXID = HASH256([version][inputs][outputs][locktime])

This creates a completely unique 32-byte hash result for each transaction.

You use these TXIDs when searching for a transaction in a blockchain explorer, or when you want to spend the output of a transaction in a new transaction.

The TXIDs of transactions are also hashed together to create a merkle root for the block header. This basically creates a "fingerprint" for the transactions that have been included in the block, so if any of the transactions change, so will the fingerprint.

wTXID

Diagram showing how a wTXID (Witness TXID) is constructed from raw transaction data (including witness data).
wTXID

Every transaction also has a witness TXID (wTXID).

A wTXID is created by double-SHA256ing the transaction data, but this time it includes the additional fields in a segwit transaction:

wTXID = HASH256([version][marker][flag][inputs][outputs][locktime][witness])

This wTXID is not used for searching or referencing transactions. It's only created so that we can include a "fingerprint" of all the extra fields of data from segregated witness transactions too (which goes in to the witness field of the coinbase transaction).

A legacy transaction will the same wTXID and TXID because it does not have the [marker], [flag] or [witness] fields.

Size

How do you measure the size of a transaction?

Diagram showing how the size of a transaction is calculated in bytes. Diagram showing how the size of a transaction is calculated in weight units. Diagram showing how the size of a transaction is calculated in virtual bytes.

A transaction has 3 size measurements:

  1. Bytes. This is simply the number of raw bytes in the transaction. It's used for working out how much space a transaction takes up on disk.
  2. Weight. This is the number of bytes in the transaction multiplied by 4, except for the size of the marker, flag, and witness fields. This weight measurement is used for working out how many transactions can fit inside a block, and it's basically used so that we can give a discount to the witness data.
  3. Virtual Bytes. This is the weight divided by 4. It's used on block explorers for comparing transaction fee rates between legacy transactions (bytes) and segwit transactions (weight).

You'll most likely run in to the virtual bytes (vBytes) measurement when inspecting transactions on blockchain explorers. It's basically the size of the transaction in bytes, except each byte of witness data is counted as 0.25 of a byte. It's the most practical and universal way of measuring the "size" of transactions in terms of how many transactions can fit in to a block.

Fee

Diagram showing how a transaction fee is the remainder of the value of a transaction's inputs minus the value of it's outputs.

A transaction fee is the remainder of a transaction.

In other words, it's the sum of the inputs minus the sum of the outputs. For example:

input  = 600 satoshis
output = 300 satoshis
output = 200 satoshis

fee    = 100 satoshis

So you set a fee on a transaction by not "using up" the total value of the inputs you have selected.

Transaction fees are collected by miners if they are able to mine a block. So the transaction fee acts as an incentive for miners to include your transaction in their candidate block.

The remainder of a transaction is always the fee. So if you incorrectly size your outputs when constructing a transaction, you could accidentally give a massive fee to the miner. So be careful.

Summary

This is how Satoshi describes a transaction:

We define an electronic coin as a chain of digital signatures. Each owner transfers the coin to the next by digitally signing a hash of the previous transaction and the public key of the next owner and adding these to the end of the coin. A payee can verify the signatures to verify the chain of ownership.
Satoshi Nakamoto, Bitcoin Whitepaper

But at the end of the day, a bitcoin transaction is just a bunch of bytes. And if you decode them, you'll find that they're just unlocking batches of bitcoins and locking them up in to new batches.

That's all there is to it.

It's pretty cool to be able to decode raw bytes of data and see bitcoins being moved from one place to another. Raw transactions may look unreadable at first, but if you can work out the size of each field and how they're formatted, anyone can decode them to see what they're doing. And if you can figure out how to decode one transaction, you can decode every transaction in the blockchain.

You'll find that transactions after 2016 have a slightly different structure due to the segregated witness upgrade, but this is just the addition of three extra fields, and it's easy enough to handle them if you've already got the hang of decoding legacy transactions.

So if you're interested in how bitcoin works, decoding a raw transaction is a good place to start.

tool-66208b48e2803
Tool Icon

Transaction Builder

Build raw transaction data.

Type
0d
  • Basic Transaction
Inputs (1)
Input 0
  • Note: This is just a placeholder TXID given as an example.
0d
0x
Outputs (1)
Output 0
0d
0d
  • Block Height

Raw Transaction Data

0100000001aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0000000000ffffffff0100000000000000000000000000
0 secs

Resources