Step 1: is to randomly select a 32 byte number with a size between 1 and 0xFFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFE BAAE DCE6 AF48 A03B BFD2 5E8C D036 4141 as the private key
18e14a7b6a307f426a94f8114701e7c8e774e7f9a47e2c2035db29a206321725
Step 2, use the elliptic curve encryption algorithm (ECDSA-SECP256k1) to calculate the uncompressed public key corresponding to the private key (a total of 65 bytes, 1 byte 0x04, 32 bytes as the x-coordinate, and 32 bytes as the y-coordinate).
0450863AD64A87AE8A2FE83C1AF1A8403CB53F53E486D8511DAD8A04887E5B23522CD470243453A299FA9E77237716103ABC11A1DF38855ED6F2EE187E9C582BA6
Step 3: Calculate the SHA-256 hash value of the public key
600FFE422B4E00731A59557A5CCA46CC183944191006324A447BDB2D98D4B408
Step 4:calculate the RIPEMD-160 hash value of the previous step’s hash value
010966776006953D5567439E5E39F86A0D273BEE
Step 5, add the address version number (such as Bitcoin mainnet version number “0x00”) between the results of the previous step
00010966776006953D5567439E5E39F86A0D273BEE
Step 6: Calculate the SHA-256 hash value of the previous step’s result
445C7A8007A93D8733188288BB320A8FE2DEBD2AE1B47F0F50BC10BAE845C094
Step 7, recalculate the SHA-256 hash value of the previous step’s result
D61967F63C7DD183914A4AE452C9F6AD5D462CE3D277798075B107615C1A8A30
Step 8, take the first 4 bytes (8-bit hexadecimal number) D61967F6 from the previous step’s result, and add these 4 bytes to the end of the fifth step’s result as a checksum (this is the hexadecimal form of Bitcoin address)
00010966776006953D5567439E5E39F86A0D273BEED61967F6
Step 9, use base58 notation to transform the address (this is the most common form of Bitcoin address)
16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM
import hashlib
from ecdsa import SECP256k1, SigningKey
import sys
import binascii
# 58 character alphabet used
BASE58_ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
def from_bytes (data, big_endian = False):
if isinstance(data, str):
data = bytearray(data)
if big_endian:
data = reversed(data)
num = 0
for offset, byte in enumerate(data):
num += byte << (offset * 8)
return num
def base58_encode(version, public_address):
"""
Gets a Base58Check string
See https://en.bitcoin.it/wiki/Base58Check_encoding
"""
if sys.version_info.major > 2:
version = bytes.fromhex(version)
else:
version = bytearray.fromhex(version)
firstSHA256 = hashlib.sha256(version + public_address)
print("first sha256: %s"%firstSHA256.hexdigest().upper())
secondSHA256 = hashlib.sha256(firstSHA256.digest())
print("second sha256: %s"%secondSHA256.hexdigest().upper())
checksum = secondSHA256.digest()[:4]
payload = version + public_address + checksum
print("Hex address: %s"%binascii.hexlify(payload).decode().upper())
if sys.version_info.major > 2:
result = int.from_bytes(payload, byteorder="big")
else:
result = from_bytes(payload, True)
# count the leading 0s
padding = len(payload) - len(payload.lstrip(b'\0'))
encoded = []
while result != 0:
result, remainder = divmod(result, 58)
encoded.append(BASE58_ALPHABET[remainder])
return padding*"1" + "".join(encoded)[::-1]
def get_private_key(hex_string):
if sys.version_info.major > 2:
return bytes.fromhex(hex_string.zfill(64))
else:
return bytearray.fromhex(hex_string.zfill(64))
def get_public_key(private_key):
# this returns the concatenated x and y coordinates for the supplied private address
# the prepended 04 is used to signify that it's uncompressed
if sys.version_info.major > 2:
return (bytes.fromhex("04") + SigningKey.from_string(private_key, curve=SECP256k1).verifying_key.to_string())
else:
return (bytearray.fromhex("04") + SigningKey.from_string(private_key, curve=SECP256k1).verifying_key.to_string())
def get_public_address(public_key):
address = hashlib.sha256(public_key).digest()
print("public key hash256: %s"%hashlib.sha256(public_key).hexdigest().upper())
h = hashlib.new('ripemd160')
h.update(address)
address = h.digest()
print("RIPEMD-160: %s"%h.hexdigest().upper())
return address
if __name__ == "__main__":
#private_key = get_private_key("FEEDB0BDEADBEEF")
private_key = get_private_key("18e14a7b6a307f426a94f8114701e7c8e774e7f9a47e2c2035db29a206321725")
print("private key: %s"%binascii.hexlify(private_key).decode().upper())
public_key = get_public_key(private_key)
print("public_key: %s"%binascii.hexlify(public_key).decode().upper())
public_address = get_public_address(public_key)
bitcoin_address = base58_encode("00", public_address)
print("Final address %s"%bitcoin_address)