
Guia Completo para Geração e Derivação de Carteiras Bitcoin com Python e BIP44
Sempre crie uma frase de segurança única para jogos, testnets ou airdrops e evite usar sua carteira principal.
Guia Completo para Geração e Derivação de Carteiras Bitcoin com Python e BIP44
Neste artigo, exploraremos passo a passo como gerar e derivar carteiras Bitcoin utilizando bibliotecas Python e o padrão BIP44. Abordaremos desde a geração de seed a partir de uma frase mnemônica (mnemonic), até a criação de chaves privadas e endereços públicos em diversos formatos, sempre garantindo compatibilidade com padrões de segurança e SEO para seu blog.
1. Geração de Seed BIP39 a partir de Mnemonic
Utilizamos a biblioteca bip_utils
para gerar um seed BIP39 a partir de uma frase mnemônica. Essa seed é a base para derivar carteiras seguindo padrões hierárquicos como o BIP44.
from bip_utils import Bip39SeedGenerator, Bip44, Bip44Coins, Bip44Changes
mnemonic = "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo vote"
seed_bytes = Bip39SeedGenerator(mnemonic).Generate()
bip44_mst = Bip44.FromSeed(seed_bytes, Bip44Coins.BITCOIN)
2. Derivação dos Endereços Bitcoin (BIP44)
Com o seed gerado, criamos uma carteira BIP44 para Bitcoin e derivamos os 50 primeiros endereços na cadeia externa (recebimento).
account = bip44_mst.Purpose().Coin().Account(0)
change = account.Change(Bip44Changes.CHAIN_EXT)
for i in range(50):
addr = change.AddressIndex(i)
print(f"{addr.PrivateKey().ToWif()} - {addr.PublicKey().ToAddress()}")
print(f"p2wpkh-p2sh:{addr.PrivateKey().ToWif()} - {addr.PublicKey().ToAddress()}")
print(f"p2wpkh:{addr.PrivateKey().ToWif()} - {addr.PublicKey().ToAddress()}")
3. Validação de Frases Mnemônicas
Utilizando a biblioteca mnemonic
, é possível validar frases mnemônicas. No exemplo abaixo, testamos frases variando a última palavra para identificar uma válida.
from mnemonic import Mnemonic
mnemo = Mnemonic("english")
wordlist = mnemo.wordlist
fixed_part = ["zoo"] * 23
for last_word in wordlist:
phrase_words = fixed_part + [last_word]
phrase = " ".join(phrase_words)
if mnemo.check(phrase):
print(f"Frase válida encontrada:\n{phrase}")
4. Derivação Manual com BIP32 e Chaves Hardened
Exemplo avançado com derivação BIP32, usando HMAC e curve secp256k1, incluindo geração de chaves privadas e públicas, além de endereços em formato WIF comprimido.
import hmac
import hashlib
import struct
from ecdsa import SECP256k1
from binascii import hexlify, unhexlify
from bit import Key
seed_hex = "02e0a8b039282faf6fe0fd769cfbc4b6b4cf8758ba68220eac420e32b91ddfa673"
seed = unhexlify(seed_hex)
def bip32_master_key(seed):
I = hmac.new(b"Bitcoin seed", seed, hashlib.sha512).digest()
IL, IR = I[:32], I[32:]
return IL, IR
def bip32_ckd_hardened(privkey, chaincode, index):
hardened_index = index + 0x80000000
data = b'\x00' + privkey + struct.pack(">L", hardened_index)
I = hmac.new(chaincode, data, hashlib.sha512).digest()
IL, IR = I[:32], I[32:]
curve_order = SECP256k1.order
priv_int = int.from_bytes(privkey, 'big')
IL_int = int.from_bytes(IL, 'big')
child_priv_int = (IL_int + priv_int) % curve_order
child_privkey = child_priv_int.to_bytes(32, 'big')
child_chaincode = IR
return child_privkey, child_chaincode
master_privkey, master_chaincode = bip32_master_key(seed)
for i in range(10):
child_privkey, child_chaincode = bip32_ckd_hardened(master_privkey, master_chaincode, i)
key = Key.from_bytes(child_privkey)
print(f"{key.to_wif()} - Address: {key.address}")
print(f"p2wpkh-p2sh:{key.to_wif()} - Address: {key.address}")
print(f"p2wpkh:{key.to_wif()} - Address: {key.address}")
5. Conversão entre Chaves WIF e WIF Comprimido
Funções para conversão de chaves privadas no formato WIF para o formato comprimido, usando Base58 e checksum SHA-256 duplo.
import hashlib
BASE58_ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
def base58_decode(s):
num = 0
for c in s:
num *= 58
num += BASE58_ALPHABET.index(c)
byte_length = (num.bit_length() + 7) // 8
decoded = num.to_bytes(byte_length, byteorder='big')
n_pad = len(s) - len(s.lstrip('1'))
return b'\x00' * n_pad + decoded
def base58_encode(b):
num = int.from_bytes(b, byteorder='big')
encode = ''
while num > 0:
num, rem = divmod(num, 58)
encode = BASE58_ALPHABET[rem] + encode
n_pad = 0
for byte in b:
if byte == 0:
n_pad += 1
else:
break
return '1' * n_pad + encode
def wif_to_compressed_wif(wif):
decoded = base58_decode(wif)
if decoded[0] != 0x80:
raise ValueError("Prefixo inválido, não é uma chave WIF válida")
priv_key = decoded[1:33]
compressed = b'\x80' + priv_key + b'\x01'
checksum = hashlib.sha256(hashlib.sha256(compressed).digest()).digest()[:4]
final = compressed + checksum
return base58_encode(final)
wifs = ["5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ"]
for wif in wifs:
try:
compressed = wif_to_compressed_wif(wif)
print(f"{wif} -> {compressed}")
print(f"p2wpkh-p2sh:{compressed}")
print(f"p2wpkh:{compressed}")
except Exception as e:
print(f"Erro ao converter {wif}: {e}")
6. Operações com Curva Elíptica secp256k1
Implementação de funções para operações matemáticas essenciais na curva secp256k1, incluindo inverso modular, adição de pontos, multiplicação escalar, e geração de endereços Bitcoin.
import hashlib
import random
p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F
n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
G = (55066263022277343669578718895168534326250603453777594175500187360389116729240,
32670510020758816978083085130507043184471273380659243275938904335757337482424)
def modinv(a, p):
if a == 0:
raise ZeroDivisionError('division by zero')
lm, hm = 1, 0
low, high = a % p, p
while low > 1:
r = high // low
nm, new = hm - lm * r, high - low * r
lm, low, hm, high = nm, new, lm, low
return lm % p
def point_add(P1, P2):
if P1 is None:
return P2
if P2 is None:
return P1
x1, y1 = P1
x2, y2 = P2
if x1 == x2 and y1 != y2:
return None
if P1 == P2:
num = (3 * x1 * x1) % p
den = modinv(2 * y1, p)
lam = (num * den) % p
else:
num = (y2 - y1) % p
den = modinv(x2 - x1, p)
lam = (num * den) % p
x3 = (lam * lam - x1 - x2) % p
y3 = (lam * (x1 - x3) - y1) % p
return (x3, y3)
def scalar_mult(k, P):
result = None
addend = P
while k > 0:
if k & 1:
result = point_add(result, addend)
addend = point_add(addend, addend)
k >>= 1
return result
# Exemplos de geração de chaves e endereços podem ser adicionados conforme necessidade.
7. Previsão de Valores para Validação Extra
Exemplo simples de função para testar valores até encontrar um valor que gere um hash SHA-256 específico (simulação de brute-force).
import hashlib
def brute_force_sha256(target_hash_hex):
target_hash = bytes.fromhex(target_hash_hex)
value = 0
while True:
val_bytes = value.to_bytes(1, 'big')
if hashlib.sha256(val_bytes).digest() == target_hash:
return value
value += 1
target = "0000000000000000000000000000000000000000000000000000000000000000"
print(f"Valor encontrado: {brute_force_sha256(target)}")
Esperamos que este guia ajude você a entender e aplicar a geração e derivação de carteiras Bitcoin com Python, assim como técnicas avançadas de criptografia e manipulação de chaves.
Comentários
Comente só assim vamos crescer juntos!