You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
bitcoinbook/code/key-to-address-ecc-example.py

50 lines
2.1 KiB

from __future__ import print_function
import bitcoin
# Generate a random private key
valid_private_key = False
while not valid_private_key:
private_key = bitcoin.random_key()
decoded_private_key = bitcoin.decode_privkey(private_key, 'hex')
valid_private_key = 0 < decoded_private_key < bitcoin.N
print("Private Key (hex) is: ", private_key)
print("Private Key (decimal) is: ", decoded_private_key)
# Convert private key to WIF format
wif_encoded_private_key = bitcoin.encode_privkey(decoded_private_key, 'wif')
print("Private Key (WIF) is: ", wif_encoded_private_key)
# Add suffix "01" to indicate a compressed private key
compressed_private_key = private_key + '01'
print("Private Key Compressed (hex) is: ", compressed_private_key)
# Generate a WIF format from the compressed private key (WIF-compressed)
wif_compressed_private_key = bitcoin.encode_privkey(
Fix for Private Key (WIF-Compressed) When testing with a `private_key = '0000000000000000000000000000000000000000000000000000000000000001'` instead of `private_key = bitcoin.random_key()`, the generated Private Key (WIF-Compressed) is wrong `5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsrefhvB5QZ`, it should be `KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn`. As it turns out, the proper way to get the correct compressed WIF is to pass `'wif_compressed'` and not `'wif'` to the `bitcoin.encode_privkey` function, as pointed out in the Main.py from the bitcoin python package. ``` def encode_privkey(priv, formt, vbyte=0): if not isinstance(priv, int_types): return encode_privkey(decode_privkey(priv), formt, vbyte) if formt == 'decimal': return priv elif formt == 'bin': return encode(priv, 256, 32) elif formt == 'bin_compressed': return encode(priv, 256, 32)+b'\x01' elif formt == 'hex': return encode(priv, 16, 64) elif formt == 'hex_compressed': return encode(priv, 16, 64)+'01' elif formt == 'wif': return bin_to_b58check(encode(priv, 256, 32), 128+int(vbyte)) elif formt == 'wif_compressed': return bin_to_b58check(encode(priv, 256, 32)+b'\x01', 128+int(vbyte)) else: raise Exception("Invalid format!") ``` The fix can be done in a couple ways: `bitcoin.encode_privkey(bitcoin.decode_privkey(compressed_private_key, 'hex'), 'wif')` -> 5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsrefhvB5QZ (WRONG) `bitcoin.encode_privkey(bitcoin.decode_privkey(compressed_private_key, 'hex'), 'wif_compressed')` -> KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU9FMLM39zT (WRONG) `bitcoin.encode_privkey(bitcoin.decode_privkey(compressed_private_key, 'hex_compressed'), 'wif_compressed')` -> KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn (CORRECT) `bitcoin.encode_privkey(bitcoin.decode_privkey(private_key, 'hex'), 'wif_compressed')` -> KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn (CORRECT)
3 years ago
bitcoin.decode_privkey(compressed_private_key, 'hex_compressed'), 'wif_compressed')
# also can be done correctly with
#wif_compressed_private_key = bitcoin.encode_privkey(
# bitcoin.decode_privkey(private_key, 'hex'), 'wif_compressed')
print("Private Key (WIF-Compressed) is: ", wif_compressed_private_key)
# Multiply the EC generator point G with the private key to get a public key point
public_key = bitcoin.fast_multiply(bitcoin.G, decoded_private_key)
print("Public Key (x,y) coordinates is:", public_key)
# Encode as hex, prefix 04
hex_encoded_public_key = bitcoin.encode_pubkey(public_key, 'hex')
print("Public Key (hex) is:", hex_encoded_public_key)
# Compress public key, adjust prefix depending on whether y is even or odd
(public_key_x, public_key_y) = public_key
compressed_prefix = '02' if (public_key_y % 2) == 0 else '03'
hex_compressed_public_key = compressed_prefix + (bitcoin.encode(public_key_x, 16).zfill(64))
print("Compressed Public Key (hex) is:", hex_compressed_public_key)
# Generate bitcoin address from public key
print("Bitcoin Address (b58check) is:", bitcoin.pubkey_to_address(public_key))
# Generate compressed bitcoin address from compressed public key
print("Compressed Bitcoin Address (b58check) is:",
bitcoin.pubkey_to_address(hex_compressed_public_key))