# 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.
