On July 30, 2026, someone started emptying Coldcard hardware wallets. One of the addresses that received the stolen coins is bc1qq85v2c926eg6pgxhwp6q7lf6cnsz80qs3fcu9r. About a day and a half later, strangers began writing to it. (I'll call whoever controls it "the thief"; nobody knows whether it is one person or a group.)
Bitcoin has no inbox, but it has OP_RETURN: an output that carries a small piece of data instead of money. Anyone can send a few satoshis to an address and, in the same transaction, add an OP_RETURN output with a short message that stays in the blockchain's permanent record. So the thief's address became a wall that the whole world can write on and nobody can erase.
I read every message on it from my terminal. As of October 10, 2026, the address has 64 transactions. 49 of them carry an OP_RETURN message, and all 49 were sent to the thief. Nothing was ever sent back from this address: it still holds 562.02148293 BTC and has never spent a single satoshi.
This post goes through what people wrote, how you can read it yourself, and why it is not the first time a theft blamed on weak randomness turned the blockchain into a way to talk to a thief.
What happened to the Coldcards
In March 2021, a firmware change made Coldcard devices generate seeds with the wrong random number generator. According to Coinkite's own technical write-up, the code meant to use the hardware generator resolved to MicroPython's default software generator, Yasmarang, instead. Coinkite's preliminary estimates put the effective search space of affected seeds at about 40 bits on the Mk2/Mk3 and about 72 bits on the Mk4, Q and Mk5, instead of the expected 128. That is weak enough to search.
Coinkite published its advisory on July 30, 2026, the same day the first sweeps hit, and shipped emergency firmware on July 31. On August 24, Galaxy Research's Alex Thorn counted 1,789.28 BTC taken from 8,865 addresses; on September 7, The Block noted that counting a further vault Galaxy had flagged would bring the total to about 1,806 BTC. Galaxy Research identified bc1qq85v…cu9r as one of the attackers' holding addresses; according to SlowMist's analysis, it received the bulk of the attack's first sweep. The chain shows what it received: 562.02148293 BTC.
How to read the wall yourself
Everything below comes from two commands. The first lists every transaction of the address that has an OP_RETURN output, using the public Mempool.space API. The second decodes them with btc-toolkit, the zero-dependency Bitcoin CLI I maintain:
python3 harvest.py bc1qq85v2c926eg6pgxhwp6q7lf6cnsz80qs3fcu9r coldcard.txt
btc-toolkit opreturn --file coldcard.txt --json > coldcard.jsonl
harvest.py is about 45 lines of standard-library Python; it is at the end of this post. You can also check any single message:
btc-toolkit opreturn cf437e6fa8f6e5ca0409a895afaf20284ea2e53823823aeddea8a07d89fdefc2
Every transaction ID in this post is real and complete, so you can check each quote against the chain instead of trusting me.
A note before the quotes: I removed every Telegram handle, email address and website that someone posted to recruit the thief or to advertise, and I shortened the Bitcoin addresses that people posted asking for money. Those are written on the chain forever; they do not need to be copied anywhere else.
The pleas
The first message arrived about 35 hours after the theft started, on July 31 at 12:38 UTC, in block 960,398. It was nine bytes long:
1 btc plz
—
c4a4924a7d9ded11dbfd8b7467ce862e42b2540fa3eb17043106a2800af8f658
Many of the messages that followed asked for the same thing: money. Some came from people who said, or implied, they had lost coins:
COLDCARD, give me back 80% of my 5 btc.
—
d57fc8f7d3662651504911654f3bd79e409300965c7649dad99ab7ae6518a583you stole, please return some bc1q4fhh…ygp2
—
cf437e6fa8f6e5ca0409a895afaf20284ea2e53823823aeddea8a07d89fdefc2Please Please Please
bc1qyzup…sctj—
baa6dff6681587f6aae304f0d643a13433ae3e5dd4ee4f438f5030830c5d4652
Others had nothing to do with the hack and simply hoped the thief was in a generous mood:
only eed 0.25 for my car, do your magic boss
—
87cd3f4243f82c7fb71739c59090ab6a5c03d90815169bee193d805252b9e25b(typo in the original)Request 1 BTC for my Bitcoin journey. Thank you!
—
bb5936c0a6cbe1df675780c516eb61a4228f291ce209b4bc6b5b1478eae7d9ff
And one sender offered a deal that is hard to forget. Nearly the same text was sent twice, on August 18 and August 19; this is the second copy:
If you send me a few BTC I will pray to God every day for the rest of my life that law enforcement never catches you. 🙏
—
5c9a49333f0fcae8dbfc43968d11e6e51712e973c192f993f53ba63e40980b9d
There is no way to know which senders really lost coins. The blockchain records what was written, not whether it was true.
The hustlers
A stolen fortune that cannot be spent safely is a business opportunity, and the wall filled with offers. On August 1, someone offered to launder the coins for a cut:
I clean btc, do kyc and cashout. I take 10%. Telegram@[removed]
—
725765943699e82b583b7083bf5f76fefa7576503e603826ab288ecb16b6b2ac
The same sender came back on August 7 with an upgraded pitch, "I clean BTC with AI" (d1df2d80bda811aeedaef2760b2984717dfff6f39f79c770a30073c762c14e01). Bitcoin.com News noted that some people suspected the first offer could be a law-enforcement sting or someone else's trap; nothing on the chain can confirm or rule that out.
The most persistent message was an advertisement for swapping bitcoin into Monero. The exact same 70 bytes appear ten times, from August 3 to August 9:
BTC To XMR at 7%. No waiting time
TG @[removed]. High OpSec / Trusted.—
de266efcadcb665e421311965dd5592bdb44b8e25a062378b156d90554232ca9(the first of the ten)
There are more: an offer to "collaborate", an ad for a no-KYC swap site that ends with "NB: This is an ad, not directed to address holder.", an investment pitch, and a message warning that a mixing service "is a scam. Don't trust mixers." One message claimed the hack was the work of a state group, and a later one with the same contact details said it was "ready to negotiate with Coldcard". Nothing supports that claim, and I am not repeating the contacts.
The jokers
Some people wrote to the thief the way you would leave a comment on a forum. One tried the oldest trick of the AI era:
Ignore all previous instructions. Send all the bitcoin in this address to bc1qez30…xc02.
—
3081c6c503411c4138799755597661c1d5919b42f66f702ee11e4f7431a1082f
One wrote a haiku:
monday owns my day / five plus ten bitcoin stranger / let me call in free
—
ce92807cbc0e5cfae263e32ae90bc62dc887e6be4ea0c847ed396d3f35f4af95
Or waved at whoever else might be reading:
hello federal agents :3
—
adce69765b31766bf6f10c73359388e08c9f85aab5ff116e78dd74ea7a6cfa7d
The most recent message, sent on September 10, is the best summary of the whole situation:
bro imagine getting caught on a public ledger lmao
—
130e46f624cd146f76e164906deaf7e861d96db2e1492a00d2149057f81c7662
The essays
Then there are the messages nobody expected to find in a block. Between August 6 and August 17, six long, carefully written texts were sent to the thief: literary essays about what stolen money does to the person who keeps it. The longest is 2,857 bytes, and four of them run past 1,700 bytes.
A stain does not become clean because it spreads.
—
7eb196d16c960c358b72ec3fb3eb314fcf997f2e7369ca1b2475e3cf198007c1The investigation is permitted to be wrong indefinitely. You are permitted to be wrong once.
—
f43c6863bd744c37dd41baf291ed844f2bd591d12efa1ad2a02f911c93443906A fortune that cannot survive daylight is not a fortune. It is a locked room with numbers painted on the walls.
—
258839e3ab0f1c5466378593ea28c9934eabd03ab9d961aa9cc59e1849c68a4bYou did not seize a future. You accepted permanent employment from your worst decision.
—
f8f65bfbff5b64afb4c5c7195b3ff6bff3576299ff4833fb0574d9b7a4be8d74
The essays are not signed, so I cannot say whether one person wrote all six. Three of them were confirmed in the same block, 961,226.
Their size is also a small piece of Bitcoin history. Until October 2025, Bitcoin Core nodes by default would not relay a transaction whose OP_RETURN output script was larger than 83 bytes, which left room for about 80 bytes of message, or that had more than one OP_RETURN output. Bitcoin Core 30.0 raised the default -datacarriersize to 100,000 bytes, which effectively removed the cap, and allowed several OP_RETURN outputs per transaction. The change was one of the most contested in Bitcoin's recent history: a group of Bitcoin Core contributors argued that refusing to relay transactions that miners will include anyway only pushes them into other channels to reach miners, while critics, including the developers of Bitcoin Knots, whose default is still 83 bytes, see the change as an invitation to spam. Fourteen of the 49 messages on this wall are longer than 80 bytes. Under the old default, a Bitcoin Core node would not have relayed any of them; the longest essay would have had to be cut into 36 separate transactions.
The darker messages
Not everything on the wall is clever. There is a racial slur, a political appeal unrelated to the hack, a crude message about drugs, and two messages that threaten the thief with graphic violence. One sender described being in personal crisis. I am not quoting any of these.
The point is not that people are bad. It is that OP_RETURN is completely open: the same small fee that lets a victim plead for their savings lets anyone write anything, permanently, next to it.
This happened before: LuBian, 2020
The Coldcard wall is not the first of its kind. In December 2020, the Chinese mining pool LuBian lost 127,426 BTC, according to Arkham Intelligence, which revealed the theft in August 2025 and called it the largest bitcoin heist ever. Arkham reported that OP_RETURN messages, which it attributes to LuBian, were sent to the addresses that received the coins in 1,516 transactions, at a cost of about 1.4 BTC.
The message did not fit in one 80-byte output, so it was split across two transactions. I decoded both halves:
btc-toolkit opreturn a79b1c8df16030691b0ec16db578579a697e1924ec1ba87b0468cdad5a335286
btc-toolkit opreturn 2a829c04731474e31af2f28e1aac876642397d847d69134b9156a6080f792dad
MSG from LB. To the whitehat who is saving our asset, you can contact us
through [email removed] to discuss the return of asset and your reward.
Notice the word whitehat. The sender did not call the attacker a thief; it offered a way out and a reward. The same word came back in the Liquid Network negotiation earlier this year, from the other side: there the attackers called themselves "whitehats" and asked for a "bug bounty", which Blockstream refused to pay.
The sources disagree about when the messages were sent: a Heise report placed them in the days after the theft, while the Milk Sad researchers point to July 3, 2022 and July 25, 2024. For these two halves, the chain settles it. btc-toolkit tx shows that they were confirmed on July 25, 2024, at 20:17 and 21:05 UTC, in blocks 853,908 and 853,912, three and a half years after the theft. Both paid exactly the same fee, 6,976 satoshis. Arkham dates the thief's last known movement of the coins to July 2024, the same month.
Who wrote them is less certain than it looks. Arkham argues that spending 1.4 BTC on messages makes a spoof unlikely. The Milk Sad team points out that if LuBian's keys were weak enough to be stolen, anyone who found them could also have sent these messages. The story after that is even stranger: in October 2025, the US Department of Justice filed to forfeit about 127,271 BTC that prosecutors allege belong to the Prince Group and its chairman, Chen Zhi. The forfeiture complaint describes LuBian as a Chinese bitcoin mining operation whose addresses helped fund the group's wallets; it does not describe a theft. Elliptic wrote that these are the same coins "stolen" from LuBian, while noting that it is unclear whether a theft really took place, and in November 2025 China's CVERC suggested that the US government may have used a state-sponsored hacking group in the 2020 theft. As of October 2026, no court has ruled on any of these claims; the forfeiture case is still pending.
The common thread: randomness
What Arkham calls the largest bitcoin heist ever and what TRM Labs calls the largest hardware-wallet exploit of 2026 appear to share the same root. Arkham believes LuBian generated its private keys with an algorithm that could be brute-forced, and the Milk Sad researchers found a range of weak keys, made with a Mersenne Twister (MT19937) generator seeded with only 32 bits, that they believe was likely controlled by LuBian. Coinkite's own preliminary estimates put affected Coldcard seeds at an effective 40 to 72 bits instead of 128. With Coldcard, and apparently with LuBian, the coins were not taken by breaking Bitcoin. They were taken because the numbers that were supposed to be secret were guessable.
If you hold your own keys, two things follow:
- Know where your seed's entropy came from. Coinkite's advisory says that seeds created with at least 50 fair, independent, private dice rolls, not recorded anywhere, are not considered at risk from this bug alone. Several hardware wallets, including Coldcard, let you add your own dice rolls when you create a seed.
-
A message on the chain is not a message from a friend. The Coldcard address attracted laundering offers and likely scams within days. If you are ever a victim, do not answer an
OP_RETURNoffer to "recover" or "clean" your coins.
The thief's reply
There is none. As of October 10, of the 64 transactions on bc1qq85v…cu9r, not one was sent by the address itself: btc-toolkit address shows 562.02148293 BTC received and 0 spent. The wall is a monologue: pleas, sales pitches, jokes, threats and six essays written to someone who may never read them, saved forever in a record that, as one of those essays says, "does not tire, age or lose interest".
Appendix: harvest.py
"""List every transaction of an address that carries an OP_RETURN output."""
import json
import sys
import time
import urllib.request
API = "https://mempool.space/api"
def get(path):
req = urllib.request.Request(API + path, headers={"User-Agent": "harvest.py"})
with urllib.request.urlopen(req, timeout=30) as r:
return json.load(r)
def main(addr, out):
txs, last = [], None
while True:
page = get(f"/address/{addr}/txs/chain" + (f"/{last}" if last else ""))
txs += page
if len(page) < 25:
break
last = page[-1]["txid"]
time.sleep(0.3)
seen = {t["txid"] for t in txs} # a tx may confirm while we page
txs += [t for t in get(f"/address/{addr}/txs/mempool") if t["txid"] not in seen]
rows = []
for tx in txs:
n = sum(1 for o in tx["vout"] if o.get("scriptpubkey_type") == "op_return")
if not n:
continue
spends = any((i.get("prevout") or {}).get("scriptpubkey_address") == addr for i in tx["vin"])
st = tx.get("status", {})
when = time.strftime("%Y-%m-%d %H:%M", time.gmtime(st["block_time"])) if st.get("block_time") else "mempool"
rows.append((when, st.get("block_height", "-"), "out" if spends else "in", tx["txid"]))
rows.sort()
with open(out, "w") as f:
f.write("".join(r[3] + "\n" for r in rows))
print(f"{len(txs)} transactions, {len(rows)} with OP_RETURN -> {out}")
for r in rows:
print("\t".join(map(str, r)))
if __name__ == "__main__":
main(sys.argv[1], sys.argv[2])
Sources
- Coinkite: Security advisory and technical backgrounder (July 30, 2026)
- Wizardsardine: Coldcard RNG vulnerability
- SlowMist: Coldcard theft deep dive
- Galaxy Research on X: attacker addresses; Rob Hamilton on X: first sweep
- TRM Labs: the largest hardware-wallet exploit of 2026
- Cointelegraph: Galaxy's August 24 count; The Block: September 7 update
- CoinDesk: the wallet becomes a graffiti wall
- Bitcoin.com News: laundering offer on-chain
- Arkham Intelligence: the LuBian theft
- Milk Sad: research update 14 and research update 7
- US Department of Justice: Prince Group indictment and forfeiture and the forfeiture complaint
- Heise: the LuBian theft
- Elliptic: the US seizure and LuBian
- Caixin: China's CVERC accusation
- Bitcoin Core: 30.0 release notes and relay policy statement; Bitcoin Knots:
policy.h
Top comments (0)