我理解只要有私钥就行了。
用私钥算出公钥,公钥算出币存放地址,
代码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)