Como Converter Chaves Privadas WIF e Gerar Endereços Bitcoin com Python
Sempre crie uma frase de segurança única para jogos, testnets ou airdrops e evite usar sua carteira principal.
Como Converter Chaves Privadas WIF e Gerar Endereços Bitcoin com Python
Neste artigo, vamos explorar um tutorial completo sobre como converter chaves privadas no formato WIF (Wallet Import Format) para chaves públicas e gerar endereços Bitcoin usando Python. O código apresentado inclui funções para codificação e decodificação em Base58, operações com curvas elípticas (ECC secp256k1), funções hash SHA-256 e a geração de endereços compatíveis com o protocolo Bitcoin.
Entendendo o Formato WIF
O formato WIF é uma representação codificada de uma chave privada Bitcoin. Ele inclui um prefixo, os dados da chave privada e um checksum para validação. Esse formato facilita a importação e exportação das chaves entre carteiras Bitcoin.
Base58: Codificação e Decodificação
Base58 é um sistema de codificação que utiliza um alfabeto específico para evitar caracteres confusos e facilitar a manipulação das chaves. O código abaixo mostra as funções para codificar e decodificar em Base58:
BASE58_ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
def b58encode(b):
n = int.from_bytes(b, 'big')
result = ''
while n > 0:
n, r = divmod(n, 58)
result = BASE58_ALPHABET[r] + result
pad = 0
for byte in b:
if byte == 0:
pad += 1
else:
break
return '1' * pad + result
def b58decode(s):
n = 0
for char in s:
n *= 58
n += BASE58_ALPHABET.index(char)
result = bytearray()
while n:
result.insert(0, n & 0xff)
n >>= 8
pad = 0
for c in s:
if c == '1':
pad += 1
else:
break
return b'\x00' * pad + bytes(result)
Implementação do Algoritmo SHA-256
SHA-256 é um algoritmo de hash criptográfico fundamental para o funcionamento do Bitcoin. A seguir, um exemplo simplificado da implementação da função SHA-256 em Python:
def right_rotate(n, b):
return ((n >> b) | (n << (32 - b))) & 0xffffffff
def sha256(message):
h = [
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
]
k = [
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
]
message += b'\x80'
while (len(message) * 8 + 64) % 512 != 0:
message += b'\x00'
message += (len(message) * 8 - 8).to_bytes(8, 'big')
def chunks(l, n):
for i in range(0, len(l), n):
yield l[i:i + n]
for chunk in chunks(message, 64):
w = [int.from_bytes(chunk[i:i+4], 'big') for i in range(0, 64, 4)]
for i in range(16, 64):
s0 = right_rotate(w[i-15], 7) ^ right_rotate(w[i-15], 18) ^ (w[i-15] >> 3)
s1 = right_rotate(w[i-2], 17) ^ right_rotate(w[i-2], 19) ^ (w[i-2] >> 10)
w.append((w[i-16] + s0 + w[i-7] + s1) & 0xffffffff)
a, b, c, d, e, f, g, hh = h
for i in range(64):
S1 = right_rotate(e, 6) ^ right_rotate(e, 11) ^ right_rotate(e, 25)
ch = (e & f) ^ (~e & g)
temp1 = (hh + S1 + ch + k[i] + w[i]) & 0xffffffff
S0 = right_rotate(a, 2) ^ right_rotate(a, 13) ^ right_rotate(a, 22)
maj = (a & b) ^ (a & c) ^ (b & c)
temp2 = (S0 + maj) & 0xffffffff
hh = g
g = f
f = e
e = (d + temp1) & 0xffffffff
d = c
c = b
b = a
a = (temp1 + temp2) & 0xffffffff
h = [(x + y) & 0xffffffff for x, y in zip(h, [a, b, c, d, e, f, g, hh])]
return b''.join(x.to_bytes(4, 'big') for x in h)
Operações com Curvas Elípticas (ECC secp256k1)
Bitcoin utiliza a curva elíptica secp256k1 para gerar as chaves públicas a partir das chaves privadas. O código a seguir mostra as funções essenciais para operações de ponto na curva e multiplicação escalar:
P = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F
Gx = 55066263022277343669578718895168534326250603453777594175500187360389116729240
Gy = 32670510020758816978083085130507043184471273380659243275938904335757337482424
G = (Gx, Gy)
def inv_mod(k, p):
return pow(k, -1, 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:
m = (3 * x1 * x1) * inv_mod(2 * y1, P)
else:
m = (y2 - y1) * inv_mod(x2 - x1, P)
m %= P
x3 = (m * m - x1 - x2) % P
y3 = (m * (x1 - x3) - y1) % P
return x3, y3
def scalar_mult(k, point):
result = None
addend = point
while k:
if k & 1:
result = point_add(result, addend)
addend = point_add(addend, addend)
k >>= 1
return result
Gerando a Chave Pública e o Endereço Bitcoin
Com a chave privada decodificada, podemos gerar a chave pública e, em seguida, o endereço Bitcoin. A função abaixo faz isso, suportando chave pública comprimida e não comprimida:
def get_pubkey(privkey, compressed):
x, y = scalar_mult(privkey, G)
if compressed:
return (b'\x02' if y % 2 == 0 else b'\x03') + x.to_bytes(32, 'big')
else:
return b'\x04' + x.to_bytes(32, 'big') + y.to_bytes(32, 'big')
def ripemd160_sha256(data):
# Simulação do RIPEMD-160 usando SHA-256 como placeholder
h1 = sha256(data)
return h1[:20]
def pubkey_to_address(pubkey):
pubkey_hash = ripemd160_sha256(pubkey)
versioned = b'\x00' + pubkey_hash
checksum = sha256(sha256(versioned))[:4]
return b58encode(versioned + checksum)
Exemplo Prático
Para testar, usamos uma chave WIF conhecida, convertendo-a em chave privada, depois gerando o endereço Bitcoin:
wif = 'KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn'
privkey, compressed = wif_to_privkey(wif)
pubkey = get_pubkey(privkey, compressed)
address = pubkey_to_address(pubkey)
print("Endereço:", address)
Conclusão
Este tutorial mostrou como manipular chaves privadas no formato WIF e gerar endereços Bitcoin usando Python, com explicações detalhadas de cada etapa, desde a codificação Base58 até a operação em curvas elípticas e geração do endereço final. Essa base é importante para quem deseja entender melhor os fundamentos das criptomoedas e desenvolver aplicações seguras.

Comentários
Comente só assim vamos crescer juntos!