我理解只要有私鑰就行了。
用私鑰算出公鑰,公鑰算出幣存放地址,
代碼1:隨機生成私鑰,並算出公鑰
import os import ecdsa import binascii private_key = binascii.hexlify(os.urandom(32)).decode() print("private key = " + private_key) Private_key = bytes.fromhex(private_key) signing_key = ecdsa.SigningKey.from_string(Private_key, curve = ecdsa.SECP256k1) verifying_key = signing_key.get_verifying_key() public_key = bytes.fromhex("04") + verifying_key.to_string() print ("public key = " + public_key.hex())
代碼2:用公鑰算出幣存放地址
#!/usr/bin/env python # https://en.bitcoin.it/wiki/Protocol_documentation#Addresses import hashlib import base58 # ECDSA bitcoin Public Key pubkey = '040a6aab12b278ee45ae84afcddcbb67a142908d132da2d50908c41d2f2e7fd2468954bcfc6cd93b7ab0e6f14f8c3401a1cb29ce37c01ae729282cd5acb41629dc' # 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" + str(base58.b58encode( bytes(bytearray.fromhex(key_hash + checksum)) )) )
測試
運行代碼1:
私鑰:4f8f5f8a0e7621019e32e81eaa2fec44972d9714a6ed54657713a04b03b7c180 (共64個字符,32byte?256bit?)
公鑰:04eeb8bcc6a43c0e149ebf9875a169a9c4b6cf54139545ebdd795367f435932377e9d22c1b3e24e8a3b913d26319dba2aba1dec638749629af30de1929d9355ffa (共130個字符,65個byte?未壓縮?可壓縮成33個byte?)
代入公鑰運行代碼2:
key_hash = a22dabb5eef6c3432f4ff6971b6f966c8c330d72
checksum = 8bcac83557233e3847e1af5f0cf53584bbb1445d009bbfbf387f196e26f10919
key_hash + checksum = 00a22dabb5eef6c3432f4ff6971b6f966c8c330d72 8bcac835
bitcoin address = b'1FnXBLTf2skcn3wyjRp4uChJGJqrUfzM5N' (看起來像個正常的幣地址)
仍不明白如何得到什么是比特幣私鑰,公鑰和地址? - 知乎 (zhihu.com)當中介紹的密鑰形式?
補充:參考一個比特幣私鑰可以算出幾個地址? - 知乎 (zhihu.com)
一個私鑰對應一個公鑰。同一個公鑰可以至少得到如下 4 個地址。
- 一個 P2PK 地址
- 用完整公鑰(x, y)生成的 P2PKH 地址
- 用壓縮過的公鑰(x, y&1)生成的 P2PKH 地址
- 一個使用壓縮過的公鑰生成的 P2WPK bech32 地址
除此之外,由於 Script 可以隨便寫,所以可以生成無數個 P2SH 和 P2WSH 地址。
比特幣協定隨歷史演進到今日,目前的收款地址有三種類型: 比特幣 P2PKH 型地址:‘1’ 開頭,它存在歷史最久,所有錢包都至少有支援(可收也可發)到此型地址。 比特幣 P2SH 型地址:‘3’ 開頭,較新,2012年之後才有,也被錢包普遍支援使用中。 比特幣 Bech32 型地址:‘bc1’ 開頭,最新型,2017年底才出現,因為是 SegWit 啟用 4(分岔)後的新型地址。 Bech32 Bech32 型地址是 SegWit 啟用 4(分岔)後的新型地址。 優點:比特幣發送方的地址如果是 Bech32 型,無論是發送幣到 Bech32 型或舊型地址,手續費都比較低 缺點:目前並不是市面上所有的錢包都可以順利發送比特幣到這種新的 Bech32 型地址。 目前並不是所有的錢包都能生成此新型地址來發送比特幣,你不用 Bech32 型發送的話,發送方手續費會高一些。而用 Bech32 來收錢,大部份的錢包和交易所都已經可以發到 Bech32 地址了,只有很少數的錢包不能發送錢到 Bech32 型地址。 (參見:Bech32型地址採用現況 35) 各型地址之間理論上可以互相送、收,如果不行的話,是因為你的錢包軟體還沒有支援能收到或發送該型地址的原故。
壓縮公鑰:壓縮公鑰與未壓縮公鑰_baidu_36435503的博客-CSDN博客_壓縮公鑰
參考:python3.6中從公鑰到公共地址生成比特幣密鑰對 - 問答 - Python中文網 (cnpython.com)
關於TypeError: can only concatenate str (not "bytes") to str報錯_crystal_jiang的博客-CSDN博客
什么是比特幣私鑰,公鑰和地址? - 知乎 (zhihu.com)
一個比特幣私鑰可以算出幾個地址? - 知乎 (zhihu.com)
P2PKH/P2SH/Bech32住址? - 比特幣技術 - 比特台灣論壇 (bitcoin-tw.com)