Aggiunge visualizzazione chiavi compresse/non compresse in report HTML

This commit is contained in:
2026-01-23 09:19:42 +01:00
parent 9dda40ab87
commit 3098bbfa7d

View File

@@ -75,6 +75,20 @@ class P2PKDatabaseViewer:
stats['unspent_value_btc'] = unspent_sat / 100000000.0
stats['unspent_value_sat'] = int(unspent_sat)
# Conta chiavi compresse vs non compresse
cursor.execute('SELECT scriptpubkey FROM p2pk_addresses')
all_scripts = cursor.fetchall()
compressed_count = 0
uncompressed_count = 0
for (script,) in all_scripts:
if script and script.startswith('41') and len(script) == 134:
uncompressed_count += 1
elif script and script.startswith('21') and len(script) == 70:
compressed_count += 1
stats['compressed_count'] = compressed_count
stats['uncompressed_count'] = uncompressed_count
except Exception as e:
print(f"⚠️ Errore nel calcolo statistiche: {e}")
import traceback
@@ -91,7 +105,9 @@ class P2PKDatabaseViewer:
'unique_txs': 0,
'unspent_count': 0,
'unspent_value_btc': 0.0,
'unspent_value_sat': 0
'unspent_value_sat': 0,
'compressed_count': 0,
'uncompressed_count': 0
}
conn.close()
@@ -140,7 +156,8 @@ class P2PKDatabaseViewer:
rows_html = []
for row in p2pk_data:
pubkey = self.extract_pubkey_from_script(row[4])
scriptpubkey = row[4]
pubkey = self.extract_pubkey_from_script(scriptpubkey)
txid_short = row[2][:16] if len(row[2]) > 16 else row[2]
timestamp_str = datetime.fromtimestamp(row[6]).strftime('%Y-%m-%d %H:%M') if row[6] else 'N/A'
# row[5] è già in satoshi, lo convertiamo in BTC dividendo per 100000000
@@ -152,8 +169,19 @@ class P2PKDatabaseViewer:
utxo_status = '🟢 NON SPESO' if is_unspent else '🔴 SPESO'
utxo_class = 'unspent' if is_unspent else 'spent'
# Determina se la chiave è compressa o non compressa
if scriptpubkey and scriptpubkey.startswith('41') and len(scriptpubkey) == 134:
key_type = 'uncompressed'
key_type_badge = '<span class="key-type-badge uncompressed">📜 Non Compressa (65 bytes)</span>'
elif scriptpubkey and scriptpubkey.startswith('21') and len(scriptpubkey) == 70:
key_type = 'compressed'
key_type_badge = '<span class="key-type-badge compressed">📦 Compressa (33 bytes)</span>'
else:
key_type = 'unknown'
key_type_badge = '<span class="key-type-badge unknown">❓ Sconosciuta</span>'
row_html = f'''
<tr class="{utxo_class}">
<tr class="{utxo_class} {key_type}">
<td>{row[0]}</td>
<td><span class="block">{row[1]}</span></td>
<td>
@@ -163,7 +191,8 @@ class P2PKDatabaseViewer:
<td>{row[3]}</td>
<td>
<div class="pubkey">
{pubkey}
{key_type_badge}
<div style="margin-top: 5px;">{pubkey}</div>
<button class="copy-btn" onclick="copyToClipboard('{pubkey}')">📋</button>
</div>
</td>
@@ -462,6 +491,33 @@ class P2PKDatabaseViewer:
tr.spent {{
opacity: 0.7;
}}
.key-type-badge {{
padding: 4px 10px;
border-radius: 15px;
font-size: 0.8em;
font-weight: bold;
display: inline-block;
margin-bottom: 5px;
}}
.key-type-badge.uncompressed {{
background: #cfe2ff;
color: #084298;
border: 1px solid #9ec5fe;
}}
.key-type-badge.compressed {{
background: #d1e7dd;
color: #0a3622;
border: 1px solid #a3cfbb;
}}
.key-type-badge.unknown {{
background: #f8d7da;
color: #58151c;
border: 1px solid #f1aeb5;
}}
</style>
</head>
<body>
@@ -505,6 +561,14 @@ class P2PKDatabaseViewer:
<div class="label" style="color: #0c5460;">💎 Valore Non Speso</div>
<div class="value" style="color: #0c5460;">{stats['unspent_value_btc']:.8f} BTC</div>
</div>
<div class="stat-card" style="background: #cfe2ff;">
<div class="label" style="color: #084298;">📜 Chiavi Non Compresse</div>
<div class="value" style="color: #084298;">{stats['uncompressed_count']:,}</div>
</div>
<div class="stat-card" style="background: #d1e7dd;">
<div class="label" style="color: #0a3622;">📦 Chiavi Compresse</div>
<div class="value" style="color: #0a3622;">{stats['compressed_count']:,}</div>
</div>
</div>
<div class="content">
@@ -518,6 +582,12 @@ class P2PKDatabaseViewer:
<button class="filter-btn spent-filter" onclick="filterByStatus('spent')">🔴 Solo Spesi</button>
</div>
<div class="filter-buttons" style="margin-top: 10px;">
<button class="filter-btn" onclick="filterByKeyType('all-keys')">🔑 Tutti i Tipi</button>
<button class="filter-btn" onclick="filterByKeyType('uncompressed')">📜 Solo Non Compresse</button>
<button class="filter-btn" onclick="filterByKeyType('compressed')">📦 Solo Compresse</button>
</div>
{self._generate_table_html(p2pk_data)}
</div>
@@ -581,6 +651,32 @@ class P2PKDatabaseViewer:
}}
}}
}}
function filterByKeyType(keyType) {{
const table = document.getElementById('dataTable');
if (!table) return;
const tr = table.getElementsByTagName('tr');
// Aggiorna stato pulsanti del gruppo key-type
event.target.parentElement.querySelectorAll('.filter-btn').forEach(btn => {{
btn.classList.remove('active');
}});
event.target.classList.add('active');
// Filtra righe in base al tipo di chiave
for (let i = 1; i < tr.length; i++) {{
const row = tr[i];
if (keyType === 'all-keys') {{
row.style.display = '';
}} else if (keyType === 'uncompressed') {{
row.style.display = row.classList.contains('uncompressed') ? '' : 'none';
}} else if (keyType === 'compressed') {{
row.style.display = row.classList.contains('compressed') ? '' : 'none';
}}
}}
}}
</script>
</body>
</html>