prettydeath/tornado-demix
GitHub: prettydeath/tornado-demix
基于以太坊公开链上数据,利用金额与时间关联启发式算法对 Tornado.Cash 混币交易进行去匿名化分析的区块链取证工具。
Stars: 7 | Forks: 1
# tornado-demix
**Tornado.Cash (ETH) 去混币工具包 —— 基于公开链上数据的金额 + 时间关联分析。**




`tornado-demix` 接收一个 Ethereum 钱包地址,查找其在 Tornado.Cash
ETH 池中的存款记录,并应用**概率性去匿名化启发式算法**,以找出
可能的提款(退出)地址。它完全通过 Etherscan API 基于**公开的**区块链数据
进行工作——它不会破坏任何加密技术,其产出是*线索*,而非确凿证据。
## 关于
`tornado-demix` 将 Tornado.Cash 用户的**公开、可观察行为**转化为
调查线索。当存款者的行为具有可预测性时——即在很短的时间窗口内,以相同的面额提取相同数量的票据——固定面额的混币就会失去其隐私保证。该工具从 Etherscan
数据中检测这些模式,并以 CSV 格式报告可能的退出地址。它不破坏任何加密技术,也没有泄露任何链上不存在的数据。完整背景:[`ABOUT.md`](ABOUT.md)。
## 目录
- [关于](#about)
- [工作原理](#how-it-works)
- [安装](#install)
- [配置(通过 CSV 设置 API key)](#configure-api-key-via-csv)
- [用法](#usage)
- [单个钱包 — `demix`](#single-wallet--demix)
- [多个钱包 — `multi`](#several-wallets--multi)
- [拆分退出集群 — `cluster`](#split-exit-clusters--cluster)
- [输出](#output)
- [项目结构](#project-layout)
- [方法论](#methodology)
- [局限性](#limitations)
- [法律与伦理](#legal--ethics)
- [许可证](#license)
## 工作原理
Tornado.Cash 通过接受固定面额的存款(0.1 / 1 / 10 / 100 ETH)并在随后将其支付给新地址来实现资金混币。当用户
行为具有可预测性时,隐私保证就会减弱。该工具利用了两个公开信号:
1. **面额 + 时间。** 一次性(一张*凭证*)发送 *N* 张
某面额票据的存款者,通常会在有限的时间窗口内将相同的 *N* 张票据提取到一个或少数几个地址。
2. **费用指纹。** 提款会支付 `面额 − relayer 费用`,例如,一张 1 ETH
的票据实际到账约为 ~0.90–0.995 ETH。将资金池的支出过滤到该区间内,可以隔离出
真实的提款。
```
Deposit: N notes of denomination D at time T (a "voucher")
│
▼
Withdrawals (internal txs FROM the pool) in [T, T + window],
where a recipient received ≈ D − relayer fee
│
▼
Count unique recipients → those hit exactly N times are
candidate consolidation addresses for the depositor.
```
对于多个钱包,该工具增加了**面额特征匹配**(一个地址收到了一个钱包*完整的*多面额指纹)和**集群追踪**(将拆分退出向前追踪一跳,直到找到共享的下游地址)。
完整说明:[`docs/METHODOLOGY.md`](docs/METHODOLOGY.md)。
## 安装
```
git clone https://github.com/prettydeath/tornado-demix.git
cd tornado-demix
python -m pip install -r requirements.txt # or: pip install -e .
```
需要 Python 3.9+ 和 `requests`(标准库 `csv` 负责处理输出——没有
重量级的依赖项)。
## 配置(通过 CSV 设置 API key)
Etherscan API key 从一个 **CSV 文件**中读取——命令行中不暴露任何密钥。
```
cp config/api.csv.example config/api.csv
```
编辑 `config/api.csv`:
```
service,api_key
etherscan,YOUR_ETHERSCAN_KEY
```
在 获取免费 key。`config/api.csv` 已被 git 忽略。
作为备选方案,该工具也会读取 `ETHERSCAN_API_KEY` 环境变量。
钱包同样可以列在一个 CSV 文件(`config/wallets.csv`)中:
```
address,label
0x019b5bb2051797e33f726d0e7a8cb9b9c2003ac2,suspect-1
0x450cc23c0bc13d46288deb36913fdaaee49fcd99,suspect-2
```
## 用法
所有命令:`python -m tornado_demix ...`(如果已安装,则为 `tornado-demix `)。
### 单个钱包 — `demix`
```
python -m tornado_demix demix 0x019b5bb2051797e33f726d0e7a8cb9b9c2003ac2 \
--out-dir out/demix
```
检测凭证,并列出每种面额恰好被命中 *N* 次的接收地址。
### 多个钱包 — `multi`
```
python -m tornado_demix multi --wallets-csv config/wallets.csv --out-dir out/multi
# 或内联:
python -m tornado_demix multi 0xAAA... 0xBBB... 0xCCC... --out-dir out/multi
```
计算强链接、软重叠、**特征匹配**以及跨钱包合并地址。
### 拆分退出集群 — `cluster`
```
python -m tornado_demix cluster --wallets-csv config/wallets.csv \
--out-dir out/cluster --layer-cap 12
```
将每种面额的候选地址向前追踪一跳,以找到共享的下游地址。
正向查找和去混币层会缓存在 `--cache-dir`(默认为 `.cache/`)下,因此
中断的运行只需**重新执行即可恢复**。
### 通用选项
| 标志 | 默认值 | 含义 |
|------|---------|---------|
| `--api-csv` | `config/api.csv` | 包含 Etherscan key 的 CSV |
| `--out-dir` | — | 写入 CSV 报告文件的目录 |
| `--window-days` | `30` | 存款后的提款搜索窗口 |
| `--fee-lo` / `--fee-hi` | `0.90` / `0.995` | 作为面额比例的支出区间 |
| `--gap-hours` | `24` | 将多笔存款归为一张凭证的最大间隔时间 |
| `--layer-cap` (cluster) | `35` | 候选地址超过此数量时跳过该面额层 |
## 输出
每个命令都会打印控制台摘要,并在指定 `--out-dir` 时写入纯 **CSV**
文件(可在任何电子表格软件、`grep` 或 pandas 中打开)。时间戳为 ISO-8601 UTC。
**`demix`**
| 文件 | 内容 |
|------|----------|
| `vouchers.csv` | 检测到的凭证:面额、数量、首/末笔存款 |
| `deposits.csv` | 每笔存款:面额、时间、区块、目标、交易哈希 |
| `candidates.csv` | 数量匹配的候选退出地址(关键结果) |
| `withdrawals_ETH.csv` | 每种面额的每个合格接收地址,带有 `is_candidate` 标志 |
**`multi`**
| 文件 | 内容 |
|------|----------|
| `wallets_overview.csv` | 每个钱包的凭证与候选数量 |
| `strong_links.csv` | 被 2 个及以上钱包共享的、数量匹配的候选地址 |
| `soft_overlaps.csv` | 被 2 个及以上钱包共享的任何合格接收地址(弱关联) |
| `profile_matches.csv` | 收到钱包完整指纹的地址(强关联) |
| `cross_consolidators.csv` | 匹配 2 个及以上钱包指纹的单一地址 |
**`cluster`**
| 文件 | 内容 |
|------|----------|
| `clusters.csv` | 由 2 个及以上面额层汇聚的点 `Z` |
| `cluster_detail.csv` | 每笔贡献资金的转发交易(来源、金额、时间、哈希) |
预先生成的示例输出位于 [`examples/`](examples/)。
## 项目结构
```
tornado-demix/
├── tornado_demix/ # Python package
│ ├── constants.py # pool/router addresses, API endpoint
│ ├── config.py # CSV loaders (API key, wallets)
│ ├── etherscan.py # Etherscan V2 client (pagination, retries)
│ ├── demix.py # single-wallet core
│ ├── multi.py # cross-wallet correlation & profile matching
│ ├── cluster.py # split-exit forward tracer (resumable cache)
│ ├── report.py # CSV report writers
│ └── cli.py # argparse CLI (demix / multi / cluster)
├── config/ # *.example CSVs (real files are git-ignored)
├── examples/ # ready-made sample CSV outputs + walkthrough
├── docs/METHODOLOGY.md # detailed method & signal-strength table
├── ABOUT.md # project background
├── requirements.txt
├── pyproject.toml
└── LICENSE
```
## 设置 GitHub "About" 面板
推送后,通过 CLI 设置仓库描述和主题:
```
gh repo edit \
--description "Tornado.Cash (ETH) demixing via amount + timing correlation on public on-chain data" \
--add-topic ethereum --add-topic tornado-cash --add-topic blockchain-forensics \
--add-topic demixing --add-topic etherscan --add-topic aml --add-topic osint
```
## 方法论
请参阅 [`docs/METHODOLOGY.md`](docs/METHODOLOGY.md) 获取完整说明,包括
信号强度表和窗口重叠注意事项。
## 局限性
## 法律与伦理
本项目仅用于对**公开**区块链数据进行合法的合规、调查和学术研究
目的。您有责任在遵守所有适用法律和服务条款(包括 Etherscan 的条款)的前提下使用它。它不执行任何黑客攻击,
不利用任何漏洞,也不透露任何链上尚未公开的信息。
## 许可证
[MIT](LICENSE)
标签:Python, Web技术栈, 代码示例, 以太坊, 区块链, 区块链安全, 数据分析, 无后门, 逆向工具, 隐私溯源