§ 05

§ 05 · Transactions

TXID

A transaction's fingerprint, and its witness twin

A txid is a transaction’s name: a 32-byte hash of its contents. Change one byte of the transaction and the name changes completely.

Pearl computes it exactly as Bitcoin does. Strip the witness, hash the rest twice with SHA-256, and show the result backwards. A second name, the wtxid, hashes everything including the witness. Here are both, worked out for a real payment.

Try it

SHA256d is just SHA-256, applied to its own output. Try it on any input.

Hash playground

Change one letter and the whole fingerprint changes

SHA256d SHA-256 twice: txids, block hashes

2ec32b953f6a93c4a34869c936e7af1e9ca052bad616574340af3f60b184215f

Avalanche SHA256d · 256 bits

122 of 256 bits changed

compared with “pearl”

Runs in your browser · nothing is sent src/lib/hash.ts · raw output order

How is a txid computed?

Take this real payment from block 130,825:

A typical payment: 1 input, 2 outputs 205 bytes
01000000 00 01 01 5939557091bae792be66f26cbd83fc78f16a690a854109e8a1d115e253812133 ab020000 00 ffffffff 02 b0359f1100000000 22 5120d7ab02c96a342bdddb5d07b9f3ebd6c04e077ff41418110b9a1e5997439416b2 00c2eb0b00000000 22 512062e9da3682aab288392cf7218bafc36287288abb3ce200c5d1a50aa234073b2b 01 40 4686c7014749649b25555874c7772ecb7a44e85454893ed5888db11ebcdc82a22d74ce1a1671d02810f5ba1dca3277409e95a653ba9644099f7da26be7a86ba2 00000000
Field Bytes Value
Version version 4 @0 1 int32 little-endian. Pearl wallets and pearld coinbases use version 1; relay policy accepts 1-2.
Marker marker 1 @4 0x00 Segwit marker (BIP-144): says witness data follows the outputs.
Flag flag 1 @5 0x01 Witness flag; 0x01 is the only value Pearl accepts.
Input count vin.length 1 @6 1 CompactSize number of inputs.
Previous txid vin[0].txid 32 @7 33218153e215d1a1e80941850a696af178fc83bd6cf266be92e7ba9170553959 The transaction being spent, stored byte-reversed (internal order); shown here in normal display order.
Output index vin[0].vout 4 @39 683 Which output of that transaction is spent (uint32 LE).
scriptSig length vin[0].scriptSig.length 1 @43 0 Always 0 for non-coinbase inputs in Pearl: every spend uses the witness instead.
Sequence vin[0].sequence 4 @44 0xffffffff Final (0xffffffff): no RBF signal, no relative locktime, and locktime is ignored for this input. Pearl wallets use this.
Output count vout.length 1 @48 2 CompactSize number of outputs.
Amount vout[0].value 8 @49 295,646,640 grains (2.95646640 PRL) int64 little-endian, in grains (1 PRL = 100,000,000 grains).
Script length vout[0].scriptPubKey.length 1 @57 34 CompactSize length of the locking script.
Locking script vout[0].scriptPubKey 34 @58 prl1p674s9jt2xs4amk6aq7ul867kcp8qwll5zsvpzzu6revewsu5z6eqv9d5z4 OP_1 OP_PUSHBYTES_32 <output key Q>: a Taproot output.
Amount vout[1].value 8 @92 200,000,000 grains (2.00000000 PRL) int64 little-endian, in grains (1 PRL = 100,000,000 grains).
Script length vout[1].scriptPubKey.length 1 @100 34 CompactSize length of the locking script.
Locking script vout[1].scriptPubKey 34 @101 prl1pvt5a5d5z42egswfv7uscht7rv2rj3z4m8n3qp3w35592ydq88v4seuhn70 OP_1 OP_PUSHBYTES_32 <output key Q>: a Taproot output.
Witness items witness[0].length 1 @135 1 Number of witness stack items for input 0.
Schnorr signature length witness[0][0].length 1 @136 64 CompactSize length of this witness item.
Schnorr signature witness[0][0] 64 @137 4686c7014749649b25555874c7772ecb7a44e85454893ed5888db11ebcdc82a22d74ce1a1671d02810f5ba1dca3277409e95a653ba9644099f7da26be7a86ba2 64-byte BIP-340 signature (R.x ‖ s) with SIGHASH_DEFAULT: a Taproot key-path spend.
Locktime locktime 4 @201 0 0: no time lock.
txid
d919e02a4adfd739ceef31d98803f0ddd24e1b1fa67b0fe572cdec42c1b384c9
Size
205 bytes · 154 vbytes
Block
130,825
Fee
7,915 grains
  1. Strip the witness

    Remove the marker and flag (00 01) and the witness (01 40 4686c701…a86ba2). What’s left is version, inputs, outputs and locktime: 137 of the 205 bytes.
  2. Hash once

    SHA-256 of those 137 bytes: ab06ab7ff1c853149284c345b20af8a71e5bd69f0ff6aff81abfe5d7d01eb328.
  3. Hash again

    SHA-256 of that 32-byte result: c984b3c142eccd72e50f7ba61f1b4ed2ddf00388d931efce39d7df4a2ae019d9. This is the txid in internal byte order.
  4. Reverse for display

    Read the 32 bytes backwards: d919e02a4adfd739ceef31d98803f0ddd24e1b1fa67b0fe572cdec42c1b384c9. That’s the txid explorers show.

The 137 stripped bytes, for checking at home:

01000000 01 5939557091bae792be66f26cbd83fc78f16a690a854109e8a1d115e253812133 ab020000 00 ffffffff
02 b0359f1100000000 22 5120d7ab02c96a342bdddb5d07b9f3ebd6c04e077ff41418110b9a1e5997439416b2
   00c2eb0b00000000 22 512062e9da3682aab288392cf7218bafc36287288abb3ce200c5d1a50aa234073b2b
00000000

(Spaces and line breaks added for reading; hash the bytes without them.)

Why is it shown backwards?

Habit, inherited from Bitcoin. Early Bitcoin code treated a hash as one huge little-endian number and printed it biggest digit first, which reverses the bytes. Every Bitcoin-derived chain kept the convention, Pearl included.

So there are two orders, and both are in use:

Where Order The payment’s txid
Explorers, RPCs, wallets display (reversed) d919e02a…c1b384c9
Inside transactions (outpoints), Merkle trees internal (as hashed) c984b3c1…2ae019d9

You can see it in the payment itself: its input spends a transaction shown everywhere as 33218153…70553959, but the bytes in the input are 59395570…53812133. Same 32 bytes, opposite order. The byte order page has more.

What is the wtxid?

The same recipe applied to the whole transaction, marker, flag and witness included:

Internal order Display order
txid (137 bytes hashed) c984b3c1…2ae019d9 d919e02a4adfd739ceef31d98803f0ddd24e1b1fa67b0fe572cdec42c1b384c9
wtxid (205 bytes hashed) 30cee874…185c7d1e 1e7d5c18e8982cd32f03a9c1409bb9c92d39dd4312cfffcf2ce9eb0c74e8ce30

A transaction with no witness has wtxid = txid. Pearl’s genesis coinbase, serialized the old way with no witness, has both equal to 302f59c6f1239648bd38eddf16b22acc8c8df3c96de2e4f552bd2f38371675c1. Since it’s the only transaction in block 0, that’s also the genesis block’s Merkle root.

Why leave the witness out of the txid?

To make the name unforgeable after the fact. Before segwit, a third party could re-encode a signature in an equivalent form, which changed the txid without invalidating the transaction. Any unconfirmed transaction that spent its outputs, referring to it by the old txid, was suddenly pointing at nothing.

With the witness excluded, the txid is fixed before anyone signs. You can build and sign a chain of transactions that spend each other’s outputs, knowing their names won’t change. The wtxid still changes if the witness does; it’s used where the witness itself must be committed to.

What goes wrong when you compute one?

Four mistakes cover almost every “my txid doesn’t match” puzzle:

  • Hashing the hex text. The characters 01000000… are not the bytes 01 00 00 00…. Decode first.
  • Forgetting to strip the witness. Hash all 205 bytes and you get the wtxid, 1e7d5c18…, not the txid.
  • Hashing once. A single SHA-256 gives ab06ab7f…. The txid needs a second pass.
  • Mixing the two orders. An outpoint written with the display-order txid points at a transaction that doesn’t exist. Inside the bytes, always use internal order.

Make a guess

Two different transactions in one block with the same txid: possible?

Think of your answer first, then check it.

Answer No.

Identical txids mean identical stripped bytes, which would be the same transaction twice. Pearl’s block check rejects a block that contains a duplicate txid (the guard Bitcoin added after a 2012 Merkle-tree bug). And BIP-34 makes every coinbase unique by putting the block height in it, so even coinbases can’t collide.

Where are txids and wtxids used?

  • Outpoints. Every input names the output it spends by txid (internal order) and index.
  • The block’s Merkle root. The header commits to all txids in the block through a Merkle tree.
  • The witness commitment. A second Merkle tree over all wtxids, with the coinbase’s wtxid replaced by 32 zero bytes, is committed in the coinbase. See coinbase.
Code: txid in JavaScript

With @noble/hashes:

JavaScript
import { sha256 } from '@noble/hashes/sha2.js';
import { hexToBytes, bytesToHex } from '@noble/hashes/utils.js';

const stripped = hexToBytes('01000000015939…00000000');   // the 137 bytes above, no spaces
const internal = sha256(sha256(stripped));
const txid = bytesToHex(internal.reverse());              // d919e02a…c1b384c9

The codex

Suggested

Up and down arrows move through the results, Enter opens one, Escape closes. Anywhere on the site, slash or Command K opens this search, and the square brackets [ and ] go to the previous and next page.