
Scanner de Endereços Bitcoin a partir de Faixas de Chaves Privadas
Sempre crie uma frase de segurança única para jogos, testnets ou airdrops e evite usar sua carteira principal.
Scanner de Endereços Bitcoin a partir de Chaves Privadas
Este artigo apresenta um script em Python avançado capaz de escanear endereços Bitcoin derivados de uma faixa específica de chaves privadas. A ferramenta implementa formatos modernos como Bech32 (BIP173), P2SH-P2WPKH e P2PKH tanto comprimido quanto não comprimido. Também conecta-se a um banco de dados SQLite para verificar se os endereços gerados já foram utilizados.
Funcionamento da Ferramenta
O script inicia com a definição de uma chave privada em hexadecimal e calcula um intervalo de valores a partir dela. Em seguida, cada chave no intervalo é convertida em endereços Bitcoin nos principais formatos. Esses endereços são comparados com um banco de dados local para identificar coincidências conhecidas.
Dependências Utilizadas
sqlite3
- Interface para banco de dados SQLite.math
edecimal
- Utilizadas para cálculos de entropia.hashlib
ebase58
- Para funções criptográficas.bit
- Biblioteca Bitcoin para Python (documentação oficial).
Codificação Bech32 (BIP173)
A codificação Bech32 permite criar endereços do tipo Segwit com maior tolerância a erros e menor risco de colisões. O script implementa funções conforme o padrão BIP173 para gerar endereços a partir da chave pública.
Funções para Bech32
bech32_polymod
: cálculo do checksum.bech32_hrp_expand
: expansão do prefixo HRP ("bc").bech32_create_checksum
: geração do checksum.convertbits
: conversão de bits para formato base 5.bech32_encode
: construção final do endereço.
Intervalo de Chaves Privadas
Uma chave privada hexadecimal é transformada em inteiro decimal e usada para definir um intervalo com define_interval
. Esse intervalo é explorado para gerar múltiplas chaves e endereços:
privkey_hex = "00000000000000000000000000000000000000000000000000000000000000e0"
low, high, pk_int = define_interval(privkey_hex)
Exemplo de saída:
- Chave privada (hex): 000000...e0
- Intervalo: 224 - 287 (decimal)
- Entropia (log2): log2(224) a log2(287)
Verificação em Banco de Dados
Após a geração dos endereços, o script conecta-se ao banco SQLite configurado com a tabela enderecos
. Cada endereço gerado é verificado se existe no banco, o que pode ser útil para estudos sobre endereços conhecidos ou reutilizados.
Formatos de Endereços Gerados
Para cada chave privada no intervalo, são gerados os seguintes formatos de endereço:
- P2PKH (não comprimido): padrão antigo usado amplamente até hoje.
- P2PKH (comprimido): versão mais compacta da chave pública.
- P2SH-P2WPKH: compatível com carteiras antigas mas com suporte parcial a Segwit.
- Bech32 (P2WPKH): formato nativo Segwit mais moderno.
Exemplo de resultado
P2PKH (não comprimido) 1ExampleUncompressedAddress...
P2PKH (comprimido) 1ExampleCompressedAddress...
P2SH-P2WPKH 3ExampleP2SHAddress...
Bech32 (P2WPKH) bc1examplebech32address...
WIF não comprimido: 5KExampleUncompressedWIF...
WIF comprimido: LExampleCompressedWIF...
Exportação de Resultados
Os resultados encontrados são salvos no arquivo enderecos_encontrados.txt
para futura análise, com separação entre cada grupo de dados.
Considerações de Segurança
Este script é destinado a fins educacionais e de auditoria. Não é recomendado utilizá-lo para gerar carteiras reais. Nunca reutilize ou compartilhe suas chaves privadas.
Aviso: O uso de ferramentas de análise de chaves privadas deve ser feito com responsabilidade. Não invista ou mova fundos em criptomoedas sem compreensão total dos riscos. Faça sua própria análise antes de qualquer decisão.
Para mais informações sobre padrões e endereços Bitcoin, consulte a documentação oficial da Bitcoin.org.
# Bitcoin Address Scanner from Private Key Range
import sqlite3
import math
import hashlib
import base58
from bit import Key
from bit.format import bytes_to_wif
from decimal import Decimal, getcontext
# ========== Bech32 Utils (BIP173) ==========
CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7"
def bech32_polymod(values):
GEN = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3]
chk = 1
for v in values:
b = chk >> 25
chk = ((chk & 0x1ffffff) << 5) ^ v
for i in range(5):
if (b >> i) & 1:
chk ^= GEN[i]
return chk
def bech32_hrp_expand(hrp):
return [ord(x) >> 5 for x in hrp] + [0] + [ord(x) & 31 for x in hrp]
def bech32_create_checksum(hrp, data):
values = bech32_hrp_expand(hrp) + data
polymod = bech32_polymod(values + [0, 0, 0, 0, 0, 0]) ^ 1
return [(polymod >> 5 * (5 - i)) & 31 for i in range(6)]
def bech32_encode(hrp, data):
return hrp + '1' + ''.join([CHARSET[d] for d in data + bech32_create_checksum(hrp, data)])
def convertbits(data, frombits, tobits, pad=True):
acc = 0
bits = 0
ret = []
maxv = (1 << tobits) - 1
for b in data:
acc = (acc << frombits) | b
bits += frombits
while bits >= tobits:
bits -= tobits
ret.append((acc >> bits) & maxv)
if pad and bits:
ret.append((acc << (tobits - bits)) & maxv)
elif bits >= frombits or ((acc << (tobits - bits)) & maxv):
return None
return ret
def hash160(data: bytes) -> bytes:
return hashlib.new('ripemd160', hashlib.sha256(data).digest()).digest()
def pubkey_to_bech32(pubkey_bytes):
h160 = hash160(pubkey_bytes)
return bech32_encode('bc', [0] + convertbits(h160, 8, 5))
def p2sh_p2wpkh_address(pubkey):
redeem_script = b'\x00\x14' + hash160(pubkey)
script_hash = hash160(redeem_script)
addr_bytes = b'\x05' + script_hash
checksum = hashlib.sha256(hashlib.sha256(addr_bytes).digest()).digest()[:4]
return base58.b58encode(addr_bytes + checksum).decode()
def define_interval(privkey_hex, size=64):
pk_int = int(privkey_hex, 16)
base = (pk_int // size) * size
return base, base + size - 1, pk_int
def main():
getcontext().prec = 100
privkey_hex = "00000000000000000000000000000000000000000000000000000000000000e0"
low, high, pk_int = define_interval(privkey_hex)
print("\n=== INTERVALO DE CHAVES PRIVADAS ===")
print(f"Hex: {privkey_hex}")
print(f"Decimal: {pk_int}")
print(f"Intervalo: {low} - {high} ({hex(low)} - {hex(high)})")
# Entropia
ln2 = Decimal(math.log(2))
log_low = Decimal(low).ln() / ln2
log_high = Decimal(high).ln() / ln2
print("\n=== ENTROPIA ===")
print(f"log2(início): {log_low}")
print(f"log2(fim): {log_high}")
print(f"Δ log2: {log_high - log_low}")
# Banco de dados
conn = sqlite3.connect(r"D:\20052025\blockchair\banco.db")
cursor = conn.cursor()
cursor.execute("SELECT address FROM enderecos")
addr_set = set(row[0] for row in cursor.fetchall())
print("\n=== ENDEREÇOS GERADOS ===")
for i in range(low, high + 1):
priv_bytes = i.to_bytes(32, 'big')
wif_uncompressed = bytes_to_wif(priv_bytes, compressed=False)
wif_compressed = bytes_to_wif(priv_bytes, compressed=True)
key_un = Key(wif_uncompressed)
key_c = Key(wif_compressed)
addresses = [
("P2PKH (não comprimido)", key_un.address),
("P2PKH (comprimido)", key_c.address),
("P2SH-P2WPKH", p2sh_p2wpkh_address(key_c.public_key)),
("Bech32 (P2WPKH)", pubkey_to_bech32(key_c.public_key)),
]
found = False
for label, addr in addresses:
if addr in addr_set:
print(f"{label.ljust(25)} {addr}")
found = True
if found:
print(f"{'WIF não comprimido:'.ljust(25)} {wif_uncompressed}")
print(f"{'WIF comprimido:'.ljust(25)} {wif_compressed}")
with open("enderecos_encontrados.txt", "a") as f:
f.write(f"WIF não comprimido: {wif_uncompressed}\n")
f.write(f"WIF comprimido: {wif_compressed}\n")
for label, addr in addresses:
if addr in addr_set:
f.write(f"{label}: {addr}\n")
f.write("-" * 50 + "\n")
conn.close()
if __name__ == "__main__":
main()