# https://en.bitcoin.it/wiki/Technical_background_of_version_1_Bitcoin_addresses # http://gobittest.appspot.com # -*- coding: utf-8 -*- import hashlib import base58 prefix = "04" version_main = "00" # Step 1: 產生 256 bits 私鑰 # 32 bytes # pri_key = "18E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725" print "private key" print pri_key print # Step 2: 由私鑰產生相對應的 512 bits 公鑰 # 65 bytes: 1 byte 0x04, 32 bytes + 32 bytes # pub_key = prefix + "50863AD64A87AE8A2FE83C1AF1A8403CB53F53E486D8511DAD8A04887E5B23522CD470243453A299FA9E77237716103ABC11A1DF38855ED6F2EE187E9C582BA6" print "public key" print pub_key print # Step 3: 對公鑰執行 SHA-256 sha256_pub = hashlib.sha256(pub_key.decode('hex')).digest() print "SHA-256 hash on the public key" print sha256_pub.encode('hex') print # Step 4: 對 step 3 結果做一次 RIPEMD-160 hash ripemd160 = hashlib.new('ripemd160') ripemd160.update(sha256_pub) ripemd160_hash = ripemd160.digest().encode("hex") print "RIPEMD-160 hash on the result of SHA-256" print ripemd160_hash print # Step 5: 對 RIPEMD-160 hash 加上版本位元 version_ripemd160_hash = version_main + ripemd160_hash print "version byte + RIPEMD-160 hash" print version_ripemd160_hash print # Step 6: 對 step 5 執行 SHA-256 hash ripemd160_hash_sha256 = hashlib.sha256(version_ripemd160_hash.decode('hex')).digest() print "sha256 hash on [version byte + RIPEMD-160 hash]" print ripemd160_hash_sha256.encode("hex") print # step 7: 再次執行 sha256 ripemd160_hash_sha256_d = hashlib.sha256(ripemd160_hash_sha256).digest() print "double sha256 hash on [version byte + RIPEMD-160 hash]" print ripemd160_hash_sha256_d.encode("hex") print # step 8: 取出前四個 bytes 作為 checksum checksum = ripemd160_hash_sha256_d.encode("hex")[:8] print "Checksum" print checksum print # step 9: 將 checksum 加到 version_ripemd160_hash 生成 25-byte Bitcoin Address bitcoin_address = version_ripemd160_hash + checksum print "Bitcoin address" print bitcoin_address print # step 10: 以 Base58Check 進行編碼 print "Bitcoin address encoded by Base58" print base58.b58encode(bitcoin_address.decode('hex')) print print base58.b58encode(pri_key.decode('hex'))