Formulário de contato

Nome

E-mail *

Mensagem *

Este blog é um complemento do nosso canal no YouTube. Clique em @CanalQb para seguir e acompanhar nossos vídeos!
Imagem

Guia Completo para Geração e Derivação de Carteiras Bitcoin com Python e BIP44


@CanalQb no YouTube


@CanalQb

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