Skip to content

Overview

A Transaction is how coins and tokens are transferred on the blockchain. It comprises of a set of Transaction Inputs which will be spent to a set of Transaction Outputs. The mining nodes and full node software ensures that every transaction follows the blockchain's rules before admitting a transaction into a block.

Verification of a transaction ensures that: - The Transaction Inputs have not already been spent. - The total value contained in the Transaction Inputs is greater than (or equal) to the value specified within the Transaction Outputs. - The Transaction is syntactically and cryptographically valid, and that the previous Unspent Transaction Outputs' Locking Scripts are correctly unlocked via the Transaction Inputs' Unlocking Script.

Transaction Format

Field Length Format Description
version 1 byte unsigned integer(LE) The version of the transaction. Currently 0
input count variable variable length integer The number of inputs in the transaction.
transaction inputs variable input_count transaction inputs Each of the transaction's inputs serialized in order.
output count variable variable length integer The number of output in the transaction.
transaction outputs variable output_count transaction outputs Each of the transaction's outputs serialized in order.
lock-time 4 bytes unsigned integer(LE) The block height or timestamp after which this transaction is allowed to be included in a block. If less than 500,000,000, this is interpreted as a block height. If equal or greater than 500,000,000, this is interpreted as a unix timestamp in seconds. Ignored if all of the transaction input sequence numbers are 0xFFFFFFFF.

Note that at 10 minutes per block, it will take over 9,500 years to reach block height 500,000,000. Also note that when Bitcoin was created the unix timestamp was well over 1,000,000,000.

Additionally, since BIP-113, when the lock-time is intepreted as a time, it is compared to the median-time-past of a block, not it's timestamp.

Median-Time-Past

The median-time-past, or MTP, of a block is defined as the median block timestamp of the 11 blocks preceding a block. This is used in calculations to avoid circumstances where consecutive blocks may not have strictly increasing timestamps.

Note, however, that this means that transactions utilizing time-based locking will not be included in a block immediately after their lock-time is reached. Instead, there will need to be 6 blocks after the lock-time in order for the MTP to indicate that the lock-time has been reached. This means that such transactions will experience an additional delay of an hour on average.

Transaction Input

Transaction inputs are the "debits" of Nexa and not only designate the satoshis that will be transferred as a part of the transaction, but they also provide proof of ownership via the Unlocking Script. A Transaction Input references an unspent Transaction Output (oftern referred to as a "UTXO"), from a prior transaction. If a Transaction would like to spend multiple UTXOs, it must have multiple inputs, one for each UTXO. The Transaction Output that is being spent by a Transaction Input is often referred to as the "PrevOut", short for the "Previous Output".

Format

Field Length Format Description
type 1 byte byte MUST be 0
outpoint 32 bytes hash A reference to the UTXO set entry being spent.
unlocking script length variable variable length integer The size of the unlocking script in bytes.
unlocking script variable bytes(BE) The contents of the unlocking script.
sequence number 4 bytes unsigned integer(LE) The sequence number is interpreted as a relative lock-time for the input.
amount 8 bytes unsigned integer(LE) The quantity of satoshi being imported into this transaction from this outpoint. This MUST BE the same number as the "value" field in the Prevout that this outpoint references (or the transaction is invalid).

Relative Lock-Time Format

A transaction input's sequence number may be interpreted as a relative lock-time for the input. That is, it prevents the transaction from being mined until a certain amount of time has past (or number of blocks mined) since the transaction containing the output to be spent was mined. The 4 bytes of the sequence number are read from the input and interpreted as an unsigned integer. The lowest-order bit is denotes as the 0th bit and the highest order bit as the 31st. The following rules are used to interpret the value:

  • If bit 31 is set, there is no relative lock-time and the sequence number can be ignore for these purposes.
  • If bit 22 is set, the relative lock-time is interpreted as a number of 512-second intervals.
  • If bit 22 is not set, the relative lock-time is interpreted as a number of blocks.
  • Bits 15 through 0 are interpreted as a 16-bit unsigned integer which specify the relative lock-time quantity.

As with lock-time, when the relative lock-time is interpreted as a time, it is compared to the median-time-past of a block, not it's timestamp.

Transaction Output

Transaction outputs are the "credits" of the blockchain. All outpoints refer to transaction outputs. The set of unspent transaction outputs comprise all the coins and tokens in the network and is called the "UTXO set" for short. Each transaction output denotes a number of satoshis and the requirements for spending them. These requirements take the form of a locking script or a commitment to a locking script and its arguments (a script template) and can equate to anything from the satoshis only being spendable by the owner of a specific private key, to anyone being able to spend them, to no one being able to spend them.

While a transaction output has not been spent by another transaction (i.e. had its locking script "unlocked" by an input of a valid transaction) it is referred to as an unspent transaction output, or UTXO. A Transaction Output that is being spent by a Transaction Input is often referred to as the "PrevOut", short for the "Previous Output".

Format

Field Length Format Description
type 1 byte byte 0 for scripts. 1 for script template commitment
value 8 bytes unsigned integer(LE) The number of satoshis to be transferred.
locking script length variable variable length integer The size of the locking script in bytes.
locking script variable bytes(BE) The contents of the locking script, or the script template commitment (serialized as a push-only script)

Transaction Fee

Extra satoshis from the Transaction Inputs that are not accounted for in the Transaction Outputs may be collected by the miner as the transaction fee.

Transaction Changes

This document assumes a familiarity with Bitcoin/Bitcoin Cash transaction semantics and structure.

Transaction Hash Changes (Id and Idem)

Summary

Transaction identity is split into two roles: 1. The "transaction idem". Latin for same, all transactions with the same idem cause the same UTXO state transformation. 2. The transaction "id". Similar to Bitcoin's transaction hash, the id is (probabilistically) unique for a transaction.

Using the Idem avoids most malleability attacks. In practice, users only care about UTXO state transformation (who paid who) rather then the exact bytes in the transaction, so the Idem should be used by default in wallets. Transactions spend other transactions by Idem, allowing children to be signed before parents and preventing malleability from orphaning chains of unspent transactions. The bitcoind RPC operations generally return the Idem, but sometimes both.

The Id is used in the networking code, and in the block merkle tree. Using the Id in the networking code is necessary so an attacker can't "spoof" a valid transaction with an invalid one. Using the Id in the block merkle tree ensures participant consistency -- the blockchain converges to a specific transaction regardless of variants, and ensures that the chain-of-signatures must be retained by all full node participants.

Background

Bitcoin uses a single identity for a transaction -- the SHA256 of the serialized transaction. This allows transaction malleability attacks, because there are some bytes in the transaction that may be changed without changing the transaction signatures or the transaction's effect on the blockchain's UTXO state. Although malleability has been "solved", the solution only covers typical script types, and consists of a variety of patches that enforce constraints on transactions that seems unnecessary and arbitrary for anyone not familiar with malleability.

Recognizing that a transaction is fundamentally exactly and only a transformation of blockchain UTXO state allows for a clean input script malleability solution. From the point of view of the blockchain, all valid transactions that effect the same UTXO state transformation are equivalent, since the UTXO state is the only data that subsequent transactions can access.

If a transaction consumes (and removes) the same coins, and produces the same outputs, the final UTXO will be exactly the same regardless of how the transaction accomplished this. Therefore, for example, it does not matter how a transaction satisfies its input constraint scripts, only that it does so.

Details

The transaction DAG (directed acyclic graph, or how transactions reference each other), uses the transaction's idem.

The block merkle tree and network subsystems use the transaction id. This guarantees that the blockchain converges to a specific transaction, regardless of the existence of idems (malleated versions of the "same" transaction), and that at the network layer, an invalid idem cannot be used to hide or block a valid transaction.

Note that if a layered application uses transaction data that does not affect the UTXO (for example a data push within the satisfier script that is popped and ignored) it still might be vulnerable to transaction malleability. These applications should either commit to that data within the UTXO (preventing malleability of that data), or wait for the particular idem to be confirmed on the blockchain.

Transaction Idem Calculation

Serialize the following transaction fields using standard bitcoin serialization algorithms: * version * inputs * prevout * sequence * amount * NOTE: the satisfier script (scriptSig) is not serialized * outputs * locktime

Transaction Id Calculation

  1. Create the "satisfiersHash" by double SHA256 hashing the following byte stream: number of inputs as a little endian 4 byte number for each input: satisfier script (script sig) 0xFF
  2. Calculate the transaction Idem
  3. Concatenate the Idem with the satisfiersHash.
  4. The transaction Id is the double SHA256 of the result of step 3.

Transaction Spend Changes

Inclusion of Amount field

This change solves the simple-signer problem, prevents high-fee bugs, and prepares the system for a hybrid UTXO and account model

An "amount" field was included in each input. This field MUST match the amount (nValue) in the output that is spent. The existence of this field helps stop wallets from making errors where they incorrectly track input amounts, resulting in accidentally giving extremely large fees to miners. It also provides this information to signing-only wallets, which defuses a theoretical attack where a such a wallet is tricked into giving large fees to miners.

Note that Bitcoin Cash requires that the amount field be part of the sighash, solving the above without solving HOW wallets learn about the previous amount. This change simply provides a convenient and default way to communicate this amount.

Note that this field is redundant information to the full node and so in theory does not need to be stored or passed over the network. However, this implementation stores it, and until this space and bandwidth are at a premium, this optimization makes little sense.

Outpoints (COutPoint)

Saves 4 bytes per input and prepares the system for more sophisticated sources of UTXO entries

"Outpoints" are references to UTXO entries, or "coins" from prior transactions. There was no good name for this so the term "outpoint" was created. The outpoint used to consist of a previous transaction hash and output index. It has been modified to be a single hash which consists of:

SHA256(tx.idem, output index)

This saves 4 bytes, and is structurally more elegant. Rather than tying a UTXO "coin" to a particular source (a particular transaction's output) it recognizes a UTXO as an independent entity.

With this change, the reverse lookup (determining where a UTXO came from) cannot use the transaction Idem lookup table. A separate table must be created that maps outpoint hashes to source transactions. This table is unnecessary for normal blockchain operations, but does effect blockchain explorers and analysis tools.

Outputs (CTxOut)

Type

Outputs are versioned so that new output types can be deployed. This allows the blockchain to create entirely new constraint scripts, potentially with non-backward-compatible script machine changes. Currently 2 types are defined.

  1. Legacy: This behaves like BTC/BCH.
  2. General: See the Generalized TXO section below

Generalized TXO

The generalized TXO format will be implemented in a subsequent merge request.

Consensus Changes

Coinbase

  • The coinbase transaction MUST have 0 inputs (vin array length must be 0). All other transactions MUST have 1 or more inputs.
  • The last output (vout[vout.size()-1]) MUST be a 0 value OP_RETURN with the block height minimally encoded as the first data item, i.e.: CScript() << OP_RETURN << _nHeight; Additional data MAY be added after the height field by the miner. The length of this data is constrained by standard OP_RETURN size rules.

These changes ensure that the coinbase Idem is unique for a blockchain transformation.

Signatures

Schnorr Signatures

ECDSA signatures are removed.

Signature Hash

The signature hash field (sighash) is modified to allow multiple bytes. Since Schnorr signatures are a well-known size, we can determine exactly how may bytes comprise the sighash.

Partial Transaction Sig Hash

N Outputs

The sighash includes outputs from 0 to N-1 (i.e. [0,N) ). This allows multiple parties to engage in partial transaction interactions.