-
-
Save circulosmeos/ef6497fd3344c2c2508b92bb9831173f to your computer and use it in GitHub Desktop.
#!/usr/bin/env python | |
# https://en.bitcoin.it/wiki/Protocol_documentation#Addresses | |
import hashlib | |
import base58 | |
# ECDSA bitcoin Public Key | |
pubkey = '0450863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b23522cd470243453a299fa9e77237716103abc11a1df38855ed6f2ee187e9c582ba6' | |
# See 'compressed form' at https://en.bitcoin.it/wiki/Protocol_documentation#Signatures | |
compress_pubkey = False | |
def hash160(hex_str): | |
sha = hashlib.sha256() | |
rip = hashlib.new('ripemd160') | |
sha.update(hex_str) | |
rip.update( sha.digest() ) | |
print ( "key_hash = \t" + rip.hexdigest() ) | |
return rip.hexdigest() # .hexdigest() is hex ASCII | |
if (compress_pubkey): | |
if (ord(bytearray.fromhex(pubkey[-2:])) % 2 == 0): | |
pubkey_compressed = '02' | |
else: | |
pubkey_compressed = '03' | |
pubkey_compressed += pubkey[2:66] | |
hex_str = bytearray.fromhex(pubkey_compressed) | |
else: | |
hex_str = bytearray.fromhex(pubkey) | |
# Obtain key: | |
key_hash = '00' + hash160(hex_str) | |
# Obtain signature: | |
sha = hashlib.sha256() | |
sha.update( bytearray.fromhex(key_hash) ) | |
checksum = sha.digest() | |
sha = hashlib.sha256() | |
sha.update(checksum) | |
checksum = sha.hexdigest()[0:8] | |
print ( "checksum = \t" + sha.hexdigest() ) | |
print ( "key_hash + checksum = \t" + key_hash + ' ' + checksum ) | |
print ( "bitcoin address = \t" + (base58.b58encode( bytes(bytearray.fromhex(key_hash + checksum)) )).decode('utf-8') ) |
awesome
love it
I have a little discrepancy on final Wallet and I didn't find the divergence between your solution and me:
You have a Pubk = 0450863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b23522cd470243453a299fa9e77237716103abc11a1df38855ed6f2ee187e9c582ba6
You have a final address: 16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM
But with same Pubk y generate this address: 1PMycacnJaSqwwJqjawXBErnLsZ7RkXUAs
The code that I'm computing is this:
public_key = '0450863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b23522cd470243453a299fa9e77237716103abc11a1df38855ed6f2ee187e9c582ba6'
Checking if the last byte is odd or even
if (ord(bytearray.fromhex(public_key[-2:])) % 2 == 0):
public_key_compressed = '02'
else:
public_key_compressed = '03'
Add bytes 0x02 to the X of the key if even or 0x03 if odd
public_key_compressed += public_key[2:66]
Converting to bytearray for SHA-256 hashing
hex_str = bytearray.fromhex(public_key_compressed)
sha = hashlib.sha256()
sha.update(hex_str)
sha.hexdigest() # .hexdigest() is hex ASCII
rip = hashlib.new('ripemd160')
rip.update(sha.digest())
key_hash = rip.hexdigest()
modified_key_hash = "00" + key_hash
sha = hashlib.sha256()
hex_str = bytearray.fromhex(modified_key_hash)
sha.update(hex_str)
sha_2 = hashlib.sha256()
sha_2.update(sha.digest())
checksum = sha_2.hexdigest()[:8]
byte_25_address = modified_key_hash + checksum
Solution1: address = base58.b58encode(bytes(bytearray.fromhex(byte_25_address))).decode('utf-8')
Solution2: key_bytes = codecs.decode(modified_key_hash, 'hex')
address = base58.b58encode_check(key_bytes).decode('utf-8')
But none of these are the same that generate your code
See bitcoin-in-tiny-pieces for updated short Bitcoin scripts!