我做了一个用随机私钥生成比特币地址的程序。 一些没有单独说明的变量和方法是SECP256K1椭圆曲线的固定值。由于它们与错误无关,因此我省略了它们。
get_private_key 方法返回随机的 256 位 int 私钥。
def get_private_key():
while (True):
random_str = os.urandom(256 // 8) + str(random.random()).encode() + str(time.time()).encode()
random_num = hashlib.sha256(random_str).digest()
private_key = int.from_bytes(random_num, 'big')
if private_key < q-1:
break
return private_key
并通过以下方法生成公钥。 (double_and_add 方法返回具有两个相加计算的 256 位整数的元组。) get_compressed_public_key 方法返回不带 0x 的 33bytes 十六进制数。
def get_compressed_public_key(key):
public_key = double_and_add(key, G)
if public_key[1] % 2 == 0 :
return "02" + str(hex(public_key[0]))[2:]
else :
return "03" + str(hex(public_key[0]))[2:]
最后,粗线是发生错误的地方。 generate_bitcoin_address 方法返回 25byte btcoin 地址,hash160 方法返回 25byte 比特币地址。
def hash160(data):
sha256_hash = SHA256.new(data)
ripemd160_hash = RIPEMD160.new(sha256_hash.digest())
return ripemd160_hash.hexdigest()
def generate_bitcoin_address(key):
# Generate compressed public key
hex_val = int(key, 16)
compressed_pkey = get_compressed_public_key(hex_val)
**data = bytes.fromhex(compressed_pkey)**
hash160_val = "00" + hash160(data)
print("Public Key's hash =", hash160_val)
# Get Checksum Value
sha256_first = SHA256.new(bytes.fromhex(hash160_val))
sha256_second = SHA256.new(bytes.fromhex(sha256_first.hexdigest()))
checksum = sha256_second.hexdigest()[:8]
# Returns 25byte Bitcoin Address.
return hash160_val + checksum
当我这样运行代码时,
for i in range(100):
private_key = str(hex(get_private_key()))[2:]
address = generate_bitcoin_address(private_key)
我预计会打印 100 份公钥的哈希值。 但是,它有时会运行几次并给我以下结果。
Public key's hash = 00ededa6d1865639736123207949b0d57dfaf007ed
Public key's hash = 000069e3aabbec21d1332740e1440c651c48709819
Public key's hash = 00afc95e037950b2ea956aa6b53a7a050beb8b0630
Public key's hash = 00e20cb4fe60856bd9201f0ddc65eac5e8df69e6f8
Public key's hash = 00d2b0c84885e9e97df2db00774662ad5fe0aaf3fa
Public key's hash = 0028c2bc126e96eba5a6eee68cee5f1300fe1d87cd
Traceback (most recent call last):
File "c:\Users\asn68\Desktop\a\2.py", line 112, in <module>
address = generate_bitcoin_address(private_key)
File "c:\Users\asn68\Desktop\a\2.py", line 86, in generate_bitcoin_address
data = bytes.fromhex(compressed_pkey)
ValueError: non-hexadecimal number found in fromhex() arg at position 65
compressed_pkey 是 str 中的一个 33bytes 十六进制。无论传入什么随机私钥,compressed_pkey 必须是 33bytes hex in string。我不知道为什么控制台说它是非十六进制数。