Python 2.7 将比特币 Privkey 转换为 WIF Privkey



我刚刚作为一个编码新手完成了一个教程。教程是这样的:https://www.youtube.com/watch?v=tX-XokHf_nI。我想用 1 个易于阅读(不是神秘)的 Python 文件生成我的比特币地址/权限密钥 - 就像现在编写代码的风格一样。

本教程进入了我获得以"1"开头的比特币地址而不是以"5"开头的 privkey 的部分。另外,我缺少如何BIP38加密私钥(以" 6"开头)。正如您在比特币主网络中看到的那样。

在教程之后使用 https://en.bitcoin.it/wiki/Wallet_import_format 作为分步指南。最后,我注释掉了我自己做的尝试,因为这一切都是垃圾。(带有"SHA256 哈希扩展私钥"的部分 这在很多层面上都是错误的")我认为我将 80 字节添加到私钥的部分可能是正确的。

PS:我现在使用静态私钥,直到一切正常,这就是为什么我注释掉了非静态私钥部分的原因。它是通过我注释掉的"非静态私钥使用"部分生成的。我还注释掉了已签名的消息代码行(在代码底部),因为它们显示在教程中,对于生成密钥/地址并不重要。我还试图通过将打印等放在文件底部并排序有点不同等来"美化"代码,但事实证明 Python 2.7 不喜欢这样。

我正在使用 Python 2.7,成功安装了所有内容,代码现在可以使用注释掉的部分正常工作。我验证了它用 bitaddress.org 打印的结果,就像教程中的上传者一样。尝试搜索以找到解决方案,但我无法从搜索结果中获得任何有用的东西。

如果你能帮我解决几行缺失的代码,我会很高兴的!也可以在代码中解释/注释什么做什么。特别是对于尚未丢失的BIP38 Privkey密码加密。所以我可以看到什么是什么,可以理解。

运行 .py 脚本返回有效结果,除了我添加的 80 个字节 - 不知道这是否由我正确完成。添加 80 个字节是获取稍后以"5"开头的最终私钥的必要步骤。

运行它会打印:

This is my Private Key: 29a59e66fe370e901174a1b8296d31998da5588c7e0dba860f11d65a3adf2736
This is my 80 Byte Private Key: 8029a59e66fe370e901174a1b8296d31998da5588c7e0dba860f11d65a3adf2736
This is my Public Key: 04d370b77a4cf0078ab9e0ba3c9e78e8dd87cc047fa58d751b3719daa29ac7fbf2c3ba8338f9a08f60a74a5d3a2d10f26afa2f703b8c430eecad89d59a9df00ec5
This is my Bitcoin Address: 1B3wS8dQHtfMpFMSmtT5Fy4kHCYvxejtVo

在这里,您可以看到我的代码,根据教程,我在这里和那里进行了尽可能好的注释: (忘了注释掉"这是我散列的 ext priv 键校验和"部分,很抱歉造成混淆。这是我现在需要帮助的代码。

import os
import ecdsa
import hashlib
import base58
##  STATIC KEY USAGE
private_key_static = "29a59e66fe370e901174a1b8296d31998da5588c7e0dba860f11d65a3adf2736"
##  PRINTOUT FROM STATIC PRIVATE KEY
print "This is my Private Key: " + private_key_static
## NON STATIC PRIVATE KEY USAGE
#private_key = os.urandom(32).encode("hex")
#print "this is my private key: " + private_key
##  80-BYTE EXTENDED PRIVATE KEY
private_key_plus_80byte = (('80') + private_key_static)
##  PRINTOUT 80-BYTE EXTENDED PRIVATE KEY
print "This is my 80 Byte Private Key: " + private_key_plus_80byte
## SHA256 HASHED EXTENDED PRIVATE KEY
## THIS IS WRONG ON SO MANY LEVELS
#hashed_ext_priv_key_checksum = hashlib.sha256(hashlib.sha256(private_key_plus_80byte).digest()).digest()[:4]
#hashed_ext_priv_key_checksum = hashed_ext_priv_key_checksum.decode("hex")
#print "This is my hashed ext priv key checksum: " + hashed_ext_priv_key_checksum
##  PRIVATE! SIGNING KEY ECDSA.SECP256k1
sk = ecdsa.SigningKey.from_string(private_key_static.decode("hex"),
curve = ecdsa.SECP256k1)
##  PUBLIC! VERIFYING KEY (64 BYTE LONG, MISSING 04 BYTE AT THE BEGINNING)
vk = sk.verifying_key
##  PUBLIC KEY
public_key = ('4' + vk.to_string()).encode("hex")
##  PRINTOUT PUBLIC KEY
print "This is my Public Key: " + public_key
##  PUBLIC KEY ENCODING (2x RIPEMD160)
ripemd160 = hashlib.new('ripemd160')
ripemd160.update(hashlib.sha256(public_key.decode('hex')).digest())
middle_man = ('0') + ripemd160.digest()
checksum = hashlib.sha256(hashlib.sha256(middle_man).digest()).digest()[:4]
binary_addr = middle_man + checksum
addr = base58.b58encode(binary_addr)
print "This is my Bitcoin Address: " + addr
##  MESSAGE CONTENT
#msg = "hello world"
##  SIGN MESSAGE CONTENT
#signed_msg = sk.sign(msg)
##  VERIFY MESSAGE CONTENT
#assert vk.verify(signed_msg, "hello world")
##  PRINTOUT SIGNED MESSAGE ENCODED TO HEX
#print "This is a HEX encoded signed Message: " + signed_msg.encode("hex")

你可能从比特币维基的步骤中误解了,所有的哈希和东西都必须在键上作为字节而不是字符串来完成。

这意味着,如果要从私钥"29a59..."派生 WIF 密钥,则不必对字符串进行哈希处理,而不必"8029a59..."而是对与之对应的二进制数据进行哈希处理。

这里缺少有效的代码段

# importing binascii to be able to convert hexadecimal strings to binary data
import binascii
# Step 1: here we have the private key
private_key_static = "29a59e66fe370e901174a1b8296d31998da5588c7e0dba860f11d65a3adf2736"
# Step 2: let's add 80 in front of it
extended_key = "80"+private_key_static
# Step 3: first SHA-256
first_sha256 = hashlib.sha256(binascii.unhexlify(extended_key)).hexdigest()
# Step 4: second SHA-256
second_sha256 = hashlib.sha256(binascii.unhexlify(first_sha256)).hexdigest()
# Step 5-6: add checksum to end of extended key
final_key = extended_key+second_sha256[:8]
# Step 7: finally the Wallet Import Format is the base 58 encode of final_key
WIF = base58.b58encode(binascii.unhexlify(final_key))
print (WIF)

其中binascii.unhexlify(...)告诉我们由十六进制字符串表示的二进制数据。

其余代码工作正常;)

最新更新