On February 10, 2014 — three days after Mt. Gox suspended withdrawals — this transaction was confirmed in Block 285,160. It moved 1,882.71 BTC ($1.56M at the time). It is a confirmed malleated transaction — its scriptSig uses a non-standard encoding that changes the txid without invalidating the signature.†
The attacker used the most common malleation technique (28,595 of 29,139 documented attacks): replacing the single-byte push opcode with OP_PUSHDATA2, which uses a 3-byte encoding to push the same data. The signature and public key are identical — only the push opcode changes.
47 = OP_PUSHBYTES_71 (push next 71 bytes)21 = OP_PUSHBYTES_33 (push next 33 bytes)
4d 4700 = OP_PUSHDATA2 + length 0x0047 (71)4d 2100 = OP_PUSHDATA2 + length 0x0021 (33)47 → 4d 4700 (1 byte → 3 bytes). This adds 4 bytes to the scriptSig, changing its hash — and therefore the txid — without touching the cryptographic signature.
The txid is SHA-256d of the entire serialized transaction, including every byte of the scriptSig. Changing even one byte — even a push opcode that doesn't affect the signature — produces a completely different hash.
47 3044...d4 01 21 02d3...2f → txid X4d 4700 3044...d4 01 4d 2100 02d3...2f → txid Y
The original transaction (with txid X) was broadcast by the sender. The attacker intercepted it, replaced the push opcodes, and rebroadcast the malleated version (txid Y). The malleated version won the race to be mined in Block 285,160. The original txid X never existed on the blockchain.
Mt. Gox tracked withdrawals by txid. When a customer requested a withdrawal, the exchange would broadcast a transaction and record its txid in the database. An attacker would:
47 with 4d 4700)The malleated transaction confirmed. The attacker received their BTC. The withdrawal was complete.
The tracked txid doesn't exist on-chain. The system concludes the withdrawal failed and credits the account — enabling a second withdrawal of the same funds.
Using Google BigQuery's public Bitcoin dataset, we can find confirmed malleated transactions — those whose scriptSig starts with 4d (OP_PUSHDATA2) instead of a normal single-byte push opcode. During the Mt. Gox attack week (February 7–28, 2014), the largest confirmed malleated transactions include:
| txid (truncated) | Block | Date | BTC |
|---|---|---|---|
3c6ebac0...7458 | 285,160 | Feb 10 | 1,882.71 |
403b6c19...045c | 285,161 | Feb 10 | 1,879.38 |
52a562a5...1e61 | 285,149 | Feb 10 | 1,878.89 |
56ee4fdd...0617 | 285,153 | Feb 10 | 1,874.83 |
733b66b1...63b4 | 285,191 | Feb 11 | 1,867.79 |
According to Decker & Wattenhofer (ETH Zurich, 2014), 35,202 malleability conflict sets were detected between January 2013 and February 2014, involving 302,700 BTC. Of 28,595 attacks using the OP_PUSHDATA2 technique, 5,670 (19.46%) successfully confirmed the malleated version. The researchers concluded that while malleability attacks were real, they could not account for Mt. Gox's claimed loss of 850,000 BTC.†
Bob, trusting the original txid, had already created transaction TX_B that spends his newly received coins. TX_B references TX_A's original txid as its input — but that txid doesn't exist anymore.
Bob's coins exist — they're in the output of TX_A' (txid f9e8d7c6...5432) — but TX_B points to the wrong txid. Bob must create a new transaction TX_B' that references the correct (malleated) txid.
Now imagine Bob is an exchange. Alice requests a withdrawal. The exchange sends TX_A, records txid a1b2c3d4...7890 in its database, and waits for confirmation. Alice (the attacker) malleates TX_A before it confirms.
TX_A' confirms. Alice receives her BTC. The withdrawal is complete.
The exchange searches for txid a1b2c3d4...7890 on the blockchain. It doesn't exist. The exchange concludes the withdrawal failed.
Alice contacts support: "My withdrawal never arrived." The exchange looks up the txid — not found. They re-send the BTC. Alice has now received double the intended amount. Repeat this thousands of times across automated systems, and you have the Mt. Gox exploit.
SegWit moves the signature out of the data that gets hashed into the txid. The txid is computed from version + inputs + outputs + locktime — no scriptSig, no signature. Changing the signature changes the wtxid but not the txid. Dependent transactions can never be invalidated by signature malleation.