314 lines
7.7 KiB
Markdown
314 lines
7.7 KiB
Markdown
|
|
# Bitcoin P2PK Scanner
|
|||
|
|
|
|||
|
|
Scanner di transazioni Bitcoin Pay-to-Public-Key (P2PK) per scopi educativi e di ricerca sulla blockchain.
|
|||
|
|
|
|||
|
|
## ⚠️ Disclaimer
|
|||
|
|
|
|||
|
|
**Questo progetto è SOLO per scopi educativi e di ricerca.**
|
|||
|
|
- Non utilizzare per attività illegali
|
|||
|
|
- Rispetta sempre i termini di servizio delle API utilizzate
|
|||
|
|
- Lo scopo è studiare la struttura della blockchain Bitcoin
|
|||
|
|
|
|||
|
|
## Caratteristiche
|
|||
|
|
|
|||
|
|
- Scansione blocchi Bitcoin per identificare transazioni P2PK
|
|||
|
|
- Salvataggio dati in database SQLite
|
|||
|
|
- Verifica UTXO (controllo se le chiavi hanno ancora saldo)
|
|||
|
|
- Report HTML interattivo con ricerca e statistiche
|
|||
|
|
- Esportazione dati in CSV
|
|||
|
|
- Scansione incrementale (riprende da dove si è fermato)
|
|||
|
|
- API mempool.space con rate limiting integrato
|
|||
|
|
|
|||
|
|
## Installazione
|
|||
|
|
|
|||
|
|
### 1. Clona il repository
|
|||
|
|
|
|||
|
|
### 2. Crea l'ambiente virtuale Python
|
|||
|
|
|
|||
|
|
**Linux/macOS:**
|
|||
|
|
```bash
|
|||
|
|
python3 -m venv .venv
|
|||
|
|
source .venv/bin/activate
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Windows:**
|
|||
|
|
```cmd
|
|||
|
|
python -m venv .venv
|
|||
|
|
.venv\Scripts\activate
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3. Installa le dipendenze
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
pip install -r requirements.txt
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## Utilizzo
|
|||
|
|
|
|||
|
|
### Scanner Principale
|
|||
|
|
|
|||
|
|
Avvia lo scanner interattivo:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
python main.py
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Lo script ti chiederà:
|
|||
|
|
- **Blocco di inizio**: da quale blocco iniziare (default: ultimo blocco + 1)
|
|||
|
|
- **Blocco finale**: fino a quale blocco scansionare
|
|||
|
|
- **Delay**: tempo tra richieste API in secondi (default: 1.0s, minimo: 0.1s)
|
|||
|
|
|
|||
|
|
Esempio di sessione:
|
|||
|
|
```
|
|||
|
|
📊 Ultimo blocco scannerizzato: 0
|
|||
|
|
💡 I primi blocchi di Bitcoin (1-10000) contengono molti P2PK
|
|||
|
|
|
|||
|
|
📍 Blocco di inizio scansione (default: 1): 1
|
|||
|
|
📍 Blocco finale scansione (default: 1000): 100
|
|||
|
|
⏱️ Delay tra richieste in secondi (default: 1.0): 1.0
|
|||
|
|
|
|||
|
|
🔧 Configurazione:
|
|||
|
|
Primo blocco: 1
|
|||
|
|
Ultimo blocco: 100
|
|||
|
|
Totale blocchi: 100
|
|||
|
|
Delay richieste: 1.0s
|
|||
|
|
Tempo stimato: ~1.7 minuti
|
|||
|
|
|
|||
|
|
▶️ Avviare la scansione? (s/n): s
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Visualizzatore Database
|
|||
|
|
|
|||
|
|
Genera un report HTML interattivo:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
python view_db.py
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Questo genera il file `p2pk_report.html` con:
|
|||
|
|
- 📊 Statistiche generali (blocchi scansionati, P2PK trovati, valori)
|
|||
|
|
- 🟢 Stato UTXO (speso/non speso)
|
|||
|
|
- 🔍 Ricerca per blocco, TXID o chiave pubblica
|
|||
|
|
- 📋 Pulsanti copia per chiavi pubbliche e TXID
|
|||
|
|
|
|||
|
|
### Statistiche Rapide
|
|||
|
|
|
|||
|
|
Visualizza statistiche nel terminale:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
python view_db.py --stats
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Output esempio:
|
|||
|
|
```
|
|||
|
|
============================================================
|
|||
|
|
📁 Database: bitcoin_p2pk_study.db
|
|||
|
|
📦 Ultimo blocco scansionato: 100
|
|||
|
|
🔑 P2PK totali trovati: 45
|
|||
|
|
📊 Blocchi unici con P2PK: 23
|
|||
|
|
📈 Range blocchi: 1 - 100
|
|||
|
|
💰 Valore totale: 1234.56789012 BTC (123456789012 sat)
|
|||
|
|
📝 Transazioni uniche: 42
|
|||
|
|
------------------------------------------------------------
|
|||
|
|
💎 P2PK NON SPESI: 12
|
|||
|
|
💵 Valore non speso: 567.89012345 BTC (56789012345 sat)
|
|||
|
|
============================================================
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## Struttura Database
|
|||
|
|
|
|||
|
|
Il database SQLite contiene due tabelle:
|
|||
|
|
|
|||
|
|
### `p2pk_addresses`
|
|||
|
|
| Campo | Tipo | Descrizione |
|
|||
|
|
|-------|------|-------------|
|
|||
|
|
| id | INTEGER | ID univoco |
|
|||
|
|
| block_height | INTEGER | Altezza blocco |
|
|||
|
|
| txid | TEXT | Transaction ID |
|
|||
|
|
| output_index | INTEGER | Indice output |
|
|||
|
|
| scriptpubkey | TEXT | ScriptPubKey (chiave pubblica) |
|
|||
|
|
| value_satoshi | INTEGER | Valore in satoshi |
|
|||
|
|
| timestamp | INTEGER | Timestamp blocco |
|
|||
|
|
| is_unspent | INTEGER | 1 = non speso, 0 = speso |
|
|||
|
|
| last_checked | INTEGER | Ultimo controllo UTXO |
|
|||
|
|
|
|||
|
|
### `scan_progress`
|
|||
|
|
| Campo | Tipo | Descrizione |
|
|||
|
|
|-------|------|-------------|
|
|||
|
|
| id | INTEGER | ID (sempre 1) |
|
|||
|
|
| last_scanned_block | INTEGER | Ultimo blocco scansionato |
|
|||
|
|
| total_p2pk_found | INTEGER | Totale P2PK trovati |
|
|||
|
|
|
|||
|
|
## Scansione Incrementale
|
|||
|
|
|
|||
|
|
Il database supporta scansioni incrementali:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# Prima scansione: blocchi 1-100
|
|||
|
|
python main.py
|
|||
|
|
> Blocco di inizio: 1
|
|||
|
|
> Blocco finale: 100
|
|||
|
|
|
|||
|
|
# Seconda scansione: blocchi 101-200 (continua automaticamente)
|
|||
|
|
python main.py
|
|||
|
|
> [ENTER] (usa default: ultimo + 1)
|
|||
|
|
> Blocco finale: 200
|
|||
|
|
|
|||
|
|
# Puoi anche scansionare "indietro" o saltare range
|
|||
|
|
python main.py
|
|||
|
|
> Blocco di inizio: 500
|
|||
|
|
> Blocco finale: 1000
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Il database usa `UNIQUE(txid, output_index)` quindi non ci saranno duplicati.
|
|||
|
|
|
|||
|
|
## Performance e Rate Limiting
|
|||
|
|
|
|||
|
|
### Chiamate API per blocco
|
|||
|
|
- 1x per ottenere hash blocco
|
|||
|
|
- 1x per ottenere timestamp
|
|||
|
|
- 1+ per transazioni (paginazione: 25 tx per pagina)
|
|||
|
|
- 1x per ogni P2PK trovato (verifica UTXO)
|
|||
|
|
|
|||
|
|
**Totale**: ~3-5 chiamate API per blocco (più se ci sono molte transazioni o P2PK)
|
|||
|
|
|
|||
|
|
### Rate Limiting
|
|||
|
|
- **Delay default**: 1.0 secondo tra blocchi
|
|||
|
|
- **Minimo consigliato**: 0.1 secondi
|
|||
|
|
- mempool.space non ha limiti ufficiali documentati, ma rispetta sempre l'API
|
|||
|
|
|
|||
|
|
**Tempo stimato**:
|
|||
|
|
- 100 blocchi × 1.0s = ~1.7 minuti
|
|||
|
|
- 1000 blocchi × 1.0s = ~17 minuti
|
|||
|
|
- 10000 blocchi × 1.0s = ~2.8 ore
|
|||
|
|
|
|||
|
|
## Esportazione Dati
|
|||
|
|
|
|||
|
|
### Esportazione CSV
|
|||
|
|
|
|||
|
|
Dopo la scansione, lo script chiederà:
|
|||
|
|
```
|
|||
|
|
📤 Esportare dati in CSV? (s/n): s
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Questo genera `p2pk_export.csv` con tutte le colonne del database.
|
|||
|
|
|
|||
|
|
### Formato CSV
|
|||
|
|
|
|||
|
|
```csv
|
|||
|
|
id,block_height,txid,output_index,scriptpubkey,value_satoshi,timestamp,is_unspent,last_checked
|
|||
|
|
1,9,0437cd7f8525ceed2324359c2d0ba26006d92d85,0,4104d46c4968bde02899d2d0d...,5000000000,1231469744,0,1234567890
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## Collaborazione
|
|||
|
|
|
|||
|
|
Questo progetto supporta la collaborazione multi-utente:
|
|||
|
|
|
|||
|
|
### Condivisione Database
|
|||
|
|
Il file `.gitignore` **non** esclude:
|
|||
|
|
- `*.db` (database SQLite)
|
|||
|
|
- `*.csv` (esportazioni)
|
|||
|
|
- `*.html` (report)
|
|||
|
|
|
|||
|
|
Più persone possono:
|
|||
|
|
1. Clonare il repository con il database esistente
|
|||
|
|
2. Scansionare range di blocchi diversi
|
|||
|
|
3. Push/pull per sincronizzare i dati raccolti
|
|||
|
|
4. Collaborare per coprire più blocchi velocemente
|
|||
|
|
|
|||
|
|
### Best Practice per Collaborazione
|
|||
|
|
1. Coordinarsi sui range di blocchi da scansionare
|
|||
|
|
2. Fare pull prima di iniziare una nuova scansione
|
|||
|
|
3. Committare e pushare il database dopo ogni scansione completata
|
|||
|
|
4. Usare delay >= 1.0s per non sovraccaricare l'API
|
|||
|
|
|
|||
|
|
## Come Funziona
|
|||
|
|
|
|||
|
|
### Rilevamento P2PK
|
|||
|
|
|
|||
|
|
Lo scanner usa 4 metodi per identificare P2PK:
|
|||
|
|
|
|||
|
|
1. **Tipo esplicito**: `scriptpubkey_type == 'pubkey'`
|
|||
|
|
2. **Lunghezza script**: 67 byte (non compresso) o 35 byte (compresso)
|
|||
|
|
3. **Pattern ASM**: `<PUBKEY> OP_CHECKSIG`
|
|||
|
|
4. **Pattern HEX**: `41<pubkey>ac` o `21<pubkey>ac`
|
|||
|
|
|
|||
|
|
### Formato ScriptPubKey
|
|||
|
|
|
|||
|
|
**P2PK non compresso** (134 caratteri hex):
|
|||
|
|
```
|
|||
|
|
41 + <65 byte pubkey> + ac
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**P2PK compresso** (70 caratteri hex):
|
|||
|
|
```
|
|||
|
|
21 + <33 byte pubkey> + ac
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Verifica UTXO
|
|||
|
|
|
|||
|
|
Per ogni P2PK trovato, lo scanner verifica su mempool.space se l'output è ancora non speso:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
GET /api/tx/{txid}/outspend/{vout}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Risposta:
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"spent": false, // true se speso
|
|||
|
|
"txid": "...", // txid che ha speso (se spent=true)
|
|||
|
|
"vin": 0 // input index (se spent=true)
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## Risoluzione Problemi
|
|||
|
|
|
|||
|
|
### L'ambiente virtuale non si attiva
|
|||
|
|
|
|||
|
|
**Linux/macOS:**
|
|||
|
|
```bash
|
|||
|
|
chmod +x .venv/bin/activate
|
|||
|
|
source .venv/bin/activate
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Windows PowerShell:**
|
|||
|
|
```powershell
|
|||
|
|
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
|
|||
|
|
.venv\Scripts\Activate.ps1
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Errori API / Timeout
|
|||
|
|
|
|||
|
|
- Verifica la connessione internet
|
|||
|
|
- Aumenta il delay tra richieste: `delay: 2.0`
|
|||
|
|
- mempool.space potrebbe essere temporaneamente non disponibile
|
|||
|
|
|
|||
|
|
### Database locked
|
|||
|
|
|
|||
|
|
Se più processi accedono al database:
|
|||
|
|
```bash
|
|||
|
|
# Chiudi tutti gli script Python in esecuzione
|
|||
|
|
# Riavvia lo script
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## Blocchi Interessanti
|
|||
|
|
|
|||
|
|
I primi blocchi Bitcoin contengono molti P2PK:
|
|||
|
|
|
|||
|
|
- **Blocchi 1-10000**: Era di Satoshi, quasi tutti P2PK
|
|||
|
|
- **Blocchi 10000-100000**: Transizione verso P2PKH
|
|||
|
|
- **Blocchi 100000+**: Prevalentemente P2PKH, P2SH, SegWit
|
|||
|
|
|
|||
|
|
**Consiglio**: Inizia dai blocchi 1-10000 per trovare più P2PK.
|
|||
|
|
|
|||
|
|
## Crediti
|
|||
|
|
|
|||
|
|
- API: [mempool.space](https://mempool.space/docs/api/rest)
|
|||
|
|
- Bitcoin: [bitcoin.org](https://bitcoin.org)
|
|||
|
|
- P2PK Reference: [Bitcoin Wiki](https://en.bitcoin.it/wiki/Transaction)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
**⚠️ Ricorda**: Questo è un progetto educativo. Le chiavi pubbliche P2PK non devono essere utilizzate per scopi illeciti.
|