Aggiunge visualizzazione chiavi compresse/non compresse in report HTML
This commit is contained in:
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user