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