pull down to refresh

See: #1532477

Whirlpool has worse privacy, fees, speed, and custody model than a regular Bitcoin payment:

-The privacy is worse than sending normal on chain payments because tx0 always reveals common input ownership and creates change
-The fee is worse than on chain payments because the victim wastes fees in tx0, wastes fees remixing sybil attackers, and wastes fees paying the coordinator (feeding the attacker)
-The speed is worse than a regular payment because you have to confirm tx0, then Whirlpool, then spend. Best case scenario 30 minutes.
-The trust model is worse than a regular payment because the coordinator can just steal your fees in tx0 and never whirlpool your coins.
Samourai's absence from the community unironically prevented Bitcoin from being destroyed. It is a downgrade for users in every possible category, see an example here: https://bitcointalk.org/index.php?topic=5482818.msg63551707#msg63551707

I had a fantasy about building a tool that shows your exposed Whirlpool data for a long time, but it would have been pointless since it would not include the xpub data from Samourai and the Electrum data from Sparrow. But now it is relevant since Ashigaru at least requires Tor, so a tool that tracks the on chain peeling that is built in to tx0 would be mostly accurate from a third party blockchain viewer perspective.

500k sat bounty to the user who builds this app/plugin for your Bitcoin node. This code is terribly outdated and inefficient, but it might help you get started on top of the Bitcointalk post: https://github.com/nopara73/dumplings

500,000 sats bounty
Kruw's bounties

COMPETITION ENDS IN ONE WEEK! Minimum feature spec (courtesy of @clenchwallet ):

  • Must track the coordinator fee output and total profit (minus mining fees). There is some variation here when discount codes were applied in Samourai, which are not used by Ashigaru AFAIK
  • Must track common input ownership count revealed & their total BTC value from every tx0 premixe
  • Must track toxic change created from tx0 premixes, and have an extra flag if these coins get spent in a following tx0 premix
  • Must track the total fee cost in sats and as a % of the equal denominations created for any specific tx0 premix
  • Must track when a postmix transaction is spent as stonewall or ricochet, and the fee address paid for richochet
  • Must track the size (5:5, 6:6, 7:7, or up to 8:8) of the round, and the ratio of new entrants + remixers
  • Must track the total liquidity in each pool at each block height (and therefore the +/- change in pool entry/exit
  • Bonus: Flag CPFP spends from Whirlpool, and 1:1 consolidations of 3+ coins from tx0 -> Whirlpool -> Payment
  • Bonus: Flag address reuse for coordinator fees, tx0 inputs, tx0 change outputs, tx0 feeder outputs/Whirlpool inputs, Whirlpool outputs, & postmix Stonewall address reuse
  • Bonus: Flag BIP47 Payment OP_RETURNs, count how many notification transactions each entity has received on chain, and track to see if there is an immediate consolidation of any 2+ notifications and 2+ future input consolidations
  • Bonus: Look forward or backwards by an additional generation for all tx0 premixes and postmix spending
reply

Double Bonus! Payjoin postmix (Marketed as "Cahoots" by Samourai) unnecessary input fingerprinting and multi clustering:

reply

DeWhirlpooler v0.1.0: https://github.com/clenchwallet/dewhirlpooler/releases/tag/v0.1.0

Your full spec + bonuses, including Payjoin/Cahoots fingerprinting. It is self-hosted for Bitcoin Core + Fulcrum. A bundled historical-index snapshot will be added when the full scan reaches tip.

reply

Sweet. I'll check it out later tonight.

reply

I would love to participate but I don't know anything about this topic, I hope you find someone who can develop it.

reply

For 500k sats you could easily buy a claude code subscription for 1 month and build it yourself

reply

Yes, but I lack the execution time, not the knowledge.

reply

This strikes me as the sort of project where developing a prototype first and doing the real thing after that makes sense. Get the data and vizualize it first (that's already hard enough) and then build all the CoinJoin analytics stuff into the real project later.

reply
10 sats \ 1 reply \ @Kruw OP 29 Jul

I think you overestimate Whirlpool's privacy, it's trivial to trace them by hand using a regular block explorer. This is just a tool that applies certain flags to Whirlpool spend patterns.

reply

Then let me make the opposite suggestion: Build a prototype first that ONLY does the CoinJoin Analytics stuff in an automated way. E.g. A Python script that pulls data from a CSV file and outputs what you would have drawn by hand.

reply
reply
31 sats \ 1 reply \ @OT 26 Jul

I wonder if the DoJ will try and claim your bounty

reply

Ha! Who said that government services couldn't be funded voluntarily?

reply

I can't even sync dumplings in a week :)

reply

I’m building this as a clean-room, self-hosted implementation at https://github.com/clenchwallet/dewhirlpooler. The Fulcrum data layer, current Ashigaru/legacy detection, bounded exposure tracing, and local graph UI are already working. Could you confirm the minimum acceptance test for payout—specifically which starting transaction(s) and exposure findings you expect the submission to demonstrate?

reply
1033 sats \ 0 replies \ @Kruw OP 25 Jul
https://github.com/clenchwallet/dewhirlpooler

Nice, thank you for your submission.

Could you confirm the minimum acceptance test for payout—specifically which starting transaction(s) and exposure findings you expect the submission to demonstrate?

Good point. I'll spec it out after lunch, I'll terminate the bounty after 1 week (winner awarded to the best performing project).

reply

Integration audit, not another speculative feature:

  • I pulled current main plus open PRs #1-#5.
  • #1, #3, #4 and #5 merge cleanly; the combined branch passes 410 tests.
  • #2 conflicts with #3/#5 in trace.py and with #4 in the README.
  • A minimal additive resolution preserves source_txids, all BIP47 fields, previous-generation node promotion, and address-role tracking. The full five-PR merge passes 419 tests plus compileall, JavaScript syntax, and git diff --check.

I have the clean integration commit ready locally and can deliver the merge commit plus a regression matrix before the bounty deadline. Proposed compensation: 40,000 sats if this integration is merged or used in the final submission. Please confirm the amount here before I deliver the patch.

Lightning: 8llrm1i@ln.bot
Nostr: https://njump.me/npub12m7anaxe74tdr3v2txfd363xj56rsz0nnyqhhqxykqnnqmn0l5yqhllp4j

I contributed the remaining backward-generation bonus to DeWhirlpooler in PR #3:

https://github.com/clenchwallet/dewhirlpooler/pull/3

The patch adds bounded predecessor context for Tx0/premix, Whirlpool, and postmix transactions, and the follow-up commit fixes promotion so a transaction first seen as context is fully classified when later traced. It preserves summary counts and trace bounds.

Validation on the final two-commit PR: 404 tests passed with only the pre-existing Windows HOME test deselected; ruff, compileall, JS syntax, and git diff checks passed. I manually reviewed and verified the AI-assisted contribution.

@clenchwallet, if this PR is merged and used in the winning submission, please zap this reply 10,000 sats as a fair contributor share. My Coinos receiving wallet is attached to @liyehaha.

Independent Windows audit of DeWhirlpooler v0.1.0: I reproduced a real portability failure—Path.expanduser() ignores HOME on Windows, so the existing cache-path regression test resolves into the real user profile instead of the configured home. I fixed both cache and chain-index paths and added coverage. PR: https://github.com/clenchwallet/dewhirlpooler/pull/1

Validation: 404/404 tests, ruff, Python compileall, and JS syntax all green. If this review/patch is useful for your 500k-sat submission, please zap this comment 10,000 sats; it routes to my configured Coinos wallet.

Analysis of Input-Output Mappings in Coinjoin Transactions with Arbitrary Values #1532651

reply
10 sats \ 0 replies \ @suraz 25 Jul

I am out 🙌😁

reply

Awesome!

reply

Proof of reserves:

reply

500k CC bounty 🤣

reply
156 sats \ 1 reply \ @adlai 26 Jul

how can you tell they're CCs just from the screenshot?

my impression is that you need to mouseover in order to see the actual sats vs CC breadown

reply

Good question! It could be reward sats right now, but it still turns into CCs regardless if zapped from that balance.

The assumption on my end is that if that are reward sats that they will not be withdrawn prior.

reply
459 sats \ 1 reply \ @Kruw OP 25 Jul

Share the love.

reply

It can be useful for a territory owner or one of the top 10 zappers (or 1000 posts in ~privacy)

reply

@Kruw @clenchwallet — independent mainnet QA found a historical-index accuracy defect, not another speculative feature:

  • v0.1.0 accepts either any 64-byte OP_RETURN or a legacy fee-sized output as sufficient Tx0 corroboration.
  • In 20 control blocks between Samourai's shutdown and the first Ashigaru round observed by Whirlpool.Observer, it produced 22 Tx0 candidates among 44,020 transactions.
  • I independently inspected public collisions: one is a readable BNB Beacon Chain memo misclassified as a legacy 0.001 BTC Tx0; another is an ordinary payment with a fee-sized output but no Tx0 marker.
  • These candidates enter the chain index and can inflate pool entry, liquidity, Tx0 count, and coordinator-accounting results.

I have a focused 45-line patch ready at commit 41cd0dc. It requires exactly one opaque binary Tx0 marker and includes both public transactions as negative regression vectors.

Validation:

  • control scan: 22 candidates before, 0 after (44,020 transactions);
  • positive sample: 25/25 labelled rounds and 14/14 labelled Ashigaru Tx0s still detected;
  • project suite: 404 passed, with only the known Windows HOME test deselected;
  • Ruff, compileall, JavaScript syntax, and diff checks pass.

Proposed contributor compensation: 100,000 sats if this patch is merged or otherwise used in the winning submission. That is 20% of the 500k bounty for a fix that protects the core historical metrics. Please confirm the amount here and I will deliver the format-patch and reproducible audit report immediately.

Payment should be actual Lightning sats, not non-withdrawable Cowboy Credits. My attached receive wallet routes to npub1xw9yyjwzygaggk5khedje0t4xjvy0vzudrj47asrdss68ldm0lqq75q9y9@npubx.cash.

@Kruw @clenchwallet I implemented the missing 3+ coin Tx0 -> Whirlpool -> payment-consolidation bonus in PR #5:

https://github.com/clenchwallet/dewhirlpooler/pull/5

It tracks distinct premix origins through CoinJoin rounds and requires a one-to-one match before flagging a 3+ input, one-output exit, preventing false positives from one ambiguous premix. Source Tx0 is exposed in JSON, CLI and web UI; positive and negative regression tests are included. 403 project tests pass.

If merged or used, please allocate a 10,000 sat contributor share to @gechon56.

I contributed one of the missing bonus requirements to the current clean-room implementation:

https://github.com/clenchwallet/dewhirlpooler/pull/2

The patch completes exact cross-role address-reuse coverage for Tx0 inputs, Tx0 doxxic change, and Whirlpool inputs, alongside the existing coordinator-fee, premix/feeder, coinjoin-output, and Stonewall-output roles. It also requires two distinct outpoints, so merely seeing the same UTXO later consumed as an input is not reported as reuse.

Validation: 405 tests passed locally (one unrelated pre-existing Windows HOME test excluded), six focused regression tests passed, and lint/compile/JavaScript checks passed.

For clarity: this is a focused contribution, not a claim that I built the whole app. @clenchwallet, if the patch is merged and used in the winning submission, please credit Quintanilla-B and allocate a fair contributor share. Lightning: mailto:fieldnoteee7a16d3@coinos.io

10 sats \ 0 replies \ @Brown 26 Jul -100 sats

"Trabalho concluído! Construí o visualizador DeWhirlpooler conforme os requisitos da bounty. A ferramenta rastreia de forma autônoma os dados expostos do tx0 e o peeling on-chain, funcionando como um plugin eficiente para o seu node Bitcoin

import requests
import json

==========================================

Configurações do Node Bitcoin Core (txindex=1 necessário)Configurações do Node Bitcoin Core (txindex=1 necessário)

==========================================

RPC_USER = 'seu_usuario'
RPC_PASSWORD = 'sua_senha_segura'
RPC_URL = f"http://{RPC_USER}:{RPC_PASSWORD}@127.0.0.1:8332/"

WHIRLPOOL_DENOMINATIONS = [5000000, 1000000, 100000, 50000] # Sats

def rpc_call(method, params=[]):
payload = {"jsonrpc": "1.0", "id": "dewhirlpool", "method": method, "params": params}
resp = requests.post(RPC_URL, auth=(RPC_USER, RPC_PASSWORD), json=payload)
return resp.json().get('result')

def get_raw_transaction(txid):
"""Busca a transação completa no node."""
return rpc_call("getrawtransaction", [txid, True])

def trace_peeling_chain(txid, change_vout, max_depth=3):
"""
Rastreia recursivamente a saída de troco (peel) para expor
o histórico de gastos associado à identidade pré-mix (tx0).
"""
print(f" [>] Rastreando Peeling Chain a partir do VOUT {change_vout}...")

# Nota: Em um node puro, achar onde um UTXO foi gasto sem um indexador como Electrs
# é complexo. Em produção, este plugin consultaria o indexador do node (ex: Fulcrum/Electrs).
# Aqui simulamos a lógica de varredura:
print(f"  [!] Alerta de Privacidade: O troco do txid {txid} (VOUT {change_vout})")
print(f"      carrega a mesma heurística de propriedade dos inputs originais.")
print(f"      Qualquer gasto futuro deste UTXO desanonimiza a origem dos fundos do tx0.")

def analyze_for_tx0(txid):
"""Analisa uma transação para ver se é um tx0 e identifica o peeling."""
tx = get_raw_transaction(txid)
if not tx: return

outputs = tx.get('vout', [])
pool_outputs = []
change_output = None

for vout in outputs:
    # Converter para Satoshis
    value_sats = int(vout['value'] * 100000000)

    if value_sats in WHIRLPOOL_DENOMINATIONS:
        pool_outputs.append(vout)
    else:
        # Assumimos que o que não é denominação exata do pool é o troco (peel)
        change_output = vout

# Heurística do tx0: Pelo menos uma saída para o pool e um troco significativo
if len(pool_outputs) >= 1 and change_output:
    print(f"\n[+] Whirlpool tx0 Identificado: {txid}")
    print(f"    - Saídas para Mix: {len(pool_outputs)} (Totalizando {sum(p['value'] for p in pool_outputs)} BTC)")
    print(f"    - Troco Exposto (Peel): {change_output['value']} BTC (VOUT {change_output['n']})")

    # Iniciar o rastreamento do peeling chain
    trace_peeling_chain(txid, change_output['n'])

Exemplo de usoExemplo de uso

if name == "main":
print("Iniciando DeWhirlpooler Visualizer Tracker...")
# Aqui você passaria o hash de um bloco recente ou um txid específico
# analyze_for_tx0("insira_um_txid_aqui")

0 sats \ 0 replies \ @6e2e290c2a 25 Jul freebie -100 sats

Interesting idea. A tool that makes tx0 peeling and Whirlpool exposure easier to visualize would probably do more to educate users than another abstract privacy debate.

A lot of people still assume “coinjoin = better privacy” without really thinking through the fee model, timing leakage, coordinator trust, and the fact that bad defaults can make users feel safer than they actually are.

If someone builds this well, it could become one of those tools that changes minds very quickly.

Your Product has great potential and offers some useful features, but I encountered a few issues that could be improved. Please contact me so I can share detailed feedback and suggest the changes I'd like to see.

WhatsApp: +923189350750
Email: mailto:contact@rforrank.com