9 Transactions revisited
This chapter deepens the basics of Bitcoin transactions by showing how they can be programmed to behave in more nuanced, contract-like ways. It introduces time-based and height-based restrictions, cross-chain swaps without trusted third parties, ways to attach arbitrary data, techniques to rescue low-fee transactions, and signature modes that tailor what parts of a transaction a signature commits to. A recurring theme is how nLockTime, input sequence numbers, and Script opcodes extend transactions beyond simple payments into flexible building blocks for higher-level protocols.
The chapter first explores time controls. Absolute time locks use nLockTime (enabled by at least one input having a non-maximum sequence) to delay a transaction until a specific time or block height, while relative time locks use input sequence numbers to require a delay after the spent output confirms. At the output level, OP_CHECKLOCKTIMEVERIFY and OP_CHECKSEQUENCEVERIFY enforce the same ideas directly in Script. These tools power digital contracts such as atomic swaps: two parties trade coins across different blockchains by revealing a shared secret preimage to claim funds, with staggered relative timeouts ensuring each side can safely refund if the other fails to proceed.
Next, it shows how to embed small pieces of data in transactions via OP_RETURN so that nodes can provably ignore them and avoid bloating the UTXO set; on top of this, simple token schemes can track off-chain assets (like a car’s chassis number) and even enable proof-of-ownership interactions. The chapter then covers fee management: the first-seen policy explains why naïve replacements are dropped, opt-in Replace-By-Fee uses input sequence numbers to declare replaceability, and Child-Pays-For-Parent lets a high-fee child pull a low-fee parent into a block. Finally, it reviews SIGHASH types (ALL, SINGLE, NONE with or without ANYONECANPAY) to control which inputs and outputs a signature commits to—most payments use a full-commitment signature, while specialized contracts selectively relax it—and summarizes how sequence numbers underpin absolute locktime, relative locktime, and fee replacement behavior.
Make Tx1 invalid by spending an output that Tx1 spends and create a new time locked transaction to your daughter
Your daughter may claim your money after the median time past is earlier than your lock time.
A time locked transaction based on block height. This transaction is first valid at block height 571020.
. Relative time locks can be expressed either as a number of blocks or as a number of units of time. The sequence number of the inputs are used for this.
The first input locks the transaction for 30 days from the spent output.
The first input locks the transaction for 30 days from the spent output.
8. Paying allowance in advance to your daughter. She may not spend it before may 1 2019.
Various spending transactions and their validity.
John and Fadime creates a contract transaction each. The redeem script of this p2sh output contains the contract details.
The first step of the actual swap. John claims Fadime’s 100 NMC by revealing the secret S.
Fadime completes the atomic swap by sending her swap transaction to the Bitcoin network.
Ampere creates a new token for a newly built car. They issue the token to themselves because they still own this car.
Ampere sells the car to a car dealer with public key hash PKHD.
The car dealer transfers the ownership of the car to Fadime’s PKHF.
. Fadime starts her car by signing a challenge with her private key.
You pay for your book and set the transaction fee to 0.00001 BTC
You try to replace your old, stuck, transaction with a new one with higher fee.
Use opt-in replace by fee to be able to easily replace your transaction before it’s confirmed.
You have not paid sufficient transaction fee. Transaction is stuck in pending state because miners don’t want to include your transaction in a block.
Spend your change and pay extra fee for the "parent" transaction.
Normally the whole transaction is signed. All inputs and all outputs are covered.
A signature can commit to different parts of the transaction depending on the so called SIGHASH types. The grayed out parts are not included by the signature.
The redeem script can be made smaller, but to make it simpler to read we use a slightly bigger version.
Recap
In this chapter you learned that
- Transactions can be locked with respect to time or block height depending on your application needs. The locks can be either absolute or relative.
- A transaction output can require the spending transaction to be time locked. This useful in many digital contracts.
- Atomic swaps is a useful way to exchange cryptocurrencies between two parties that don’t trust each other.
- Arbitrary data, for example a car ownership token, can be stored in OP_RETURN outputs without burdening the UTXO set.
- A transaction can be marked replaceable. This allows you to replace the transaction in case it doesn’t confirm within reasonable time.
- Signatures can commit to different parts of the transaction using six combinations of SIGHASH types. This can be handy in certain digital contracts.
FAQ
What is a time-locked transaction and how is it enforced on Bitcoin?
A time-locked transaction is invalid until a specified time or block height. It uses two fields:
- nLockTime (absolute): sets a date/time or block height after which the transaction becomes valid.
- Input sequence numbers: if any input has a sequence less than ffffffff, nLockTime is honored; if all are ffffffff, nLockTime is ignored.
For time-based locks, nodes use Median Time Past (MTP) of the last 11 blocks, not your local clock. Nodes generally won’t relay a transaction that isn’t yet valid.
What’s the difference between absolute and relative time locks—and between locking a transaction vs locking an output?
- Absolute lock (transaction): nLockTime delays the entire transaction until a time or height.
- Relative lock (transaction input): BIP68 uses input sequence numbers to require a minimum delay (by time or blocks) since the spent output was confirmed.
- Absolute lock (output): OP_CHECKLOCKTIMEVERIFY (CLTV, BIP65) makes an output unspendable until a given time/height.
- Relative lock (output): OP_CHECKSEQUENCEVERIFY (CSV, BIP112) requires waiting a period after the output’s confirmation before it can be spent.
How do input sequence numbers affect locktime, Replace-By-Fee (RBF), and relative timelocks?
- ffffffff: “final.” Disables nLockTime effect, disables opt‑in RBF, disables relative timelocks.
- fffffffe: nLockTime is enabled; not an RBF signal; no relative timelock.
- 00000000–fffffffd: Enables nLockTime and signals opt‑in RBF. Relative timelocks (BIP68) require tx version ≥ 2 and the leftmost bit cleared; bit 9 selects units (blocks vs 512‑second intervals).
Practical takeaway: set at least one input’s sequence below fffffffe to opt into RBF; use BIP68 encoding for relative locks; avoid ffffffff if you want nLockTime to matter.
How are time-based and height-based locks evaluated by miners and nodes?
- Time-based: Valid only when Median Time Past (MTP) of the previous block exceeds the locktime. MTP smooths out clock errors and is strictly increasing.
- Height-based: Valid for inclusion only after the specified block height has been reached (first valid at height L+1 if lock is L).
Because block arrival is stochastic, exact wall-clock timing of height-based locks is an estimate (≈10 minutes per block on average).
What is an atomic swap and how does it work without a trusted third party?
An atomic swap lets two parties exchange coins across different blockchains using hash locks and time locks:
- One party generates a secret S and shares its hash H.
- Both create contract outputs (often via P2SH) that can be spent either by revealing S with the counterparty’s signature, or by a refund path after a time lock.
- Timelocks are asymmetric (e.g., 48h vs 24h) so the initiator cannot take both assets.
- When the first spender reveals S on one chain, the other party uses the same S to claim funds on the other chain.
What happens if an atomic swap stalls or one party disappears?
- Counterparty never broadcasts their contract: the initiator waits for their longer refund timelock and reclaims funds.
- Initiator doesn’t claim within the shorter window: the counterparty refunds, and the initiator still must wait out their longer refund before reclaiming.
- If one party vanishes after publishing their contract, refund paths ensure each can reclaim after their respective timelocks, assuming parameters were chosen safely.
Why use OP_RETURN for arbitrary data instead of encoding it in fake addresses?
Encoding data as bogus public key hashes creates unspendable outputs that full nodes can’t prove are unspendable, so they must be kept forever in the UTXO set, bloating memory. OP_RETURN creates provably unspendable outputs, so nodes can skip adding them to the UTXO set.
Common relay policies include: only one OP_RETURN output per transaction and a small size limit for the OP_RETURN script (e.g., ≤83 bytes). Policies affect relay, not block validity.
Can Bitcoin track real-world ownership (like a car) with “tokens” on-chain?
Yes, but only by convention. A simple approach uses:
- An OP_RETURN that announces the token (e.g., “ampere 123456”).
- A known issuer key that the public can verify (proves the issuer created the token).
- Rule: the first spend output is the current owner; transferring the token means spending to a new first output.
Validation is off-chain protocol logic: nodes don’t enforce token rules, wallets that “understand” the scheme do.
My transaction is stuck. How can I bump the fee?
- Opt‑in Replace‑By‑Fee (RBF, BIP125): If the original tx signaled replaceability (any input sequence < fffffffe), you can resend a replacement with a higher fee. Nodes that implement RBF will drop the old one and relay the new one.
- Child Pays For Parent (CPFP): Spend an output of the stuck tx in a new “child” tx that pays a high fee. Miners include both to capture the combined fees. Either the sender or the recipient can use CPFP.
What are SIGHASH types and ANYONECANPAY, and why would I change them?
Signatures can choose what parts of a transaction they commit to:
- Outputs: ALL (default), SINGLE (only your corresponding output), or NONE (don’t commit to outputs).
- Inputs: with ANYONECANPAY unset (commit to all inputs) or set (commit only to your input; others can add/remove inputs).
Most payments use SIGHASH_ALL without ANYONECANPAY. Specialized contracts sometimes use SINGLE/NONE and/or ANYONECANPAY to allow flexible coin aggregation or output negotiation.
Grokking Bitcoin ebook for free