Python 2.7 Converting Bitcoin Privkey to WIF Privkey

I just went through the tutorial as a newbie to coding. The tutorial was as follows: https://www.youtube.com/watch?v=tX-XokHf_nI . And I wanted to generate my bitcoin / privkeys addresses with one simple, easy-to-read (not cryptic) Python file - just as the code is written right now.

The tutorial ended up in the part where I got a bitcoin address starting with "1" but not with a jury starting with "5". Plus I am missing how BIP38 encrypts the private key (starting at "6"). This is, as you can see, for the main Bitcoin network.

Using https://en.bitcoin.it/wiki/Wallet_import_format as a step-by-step guide after the tutorial. At the end, I commented on my attempts to do it myself, because it was all rubbish. (The part with "SHA256 HASHED EXTENDED PRIVATE KEY THIS IS WRONG ON MANY LEVELS") I think the part where I added 80 bytes to the private key might be correct.

PS: I am using a static private key until now until everything works, so I commented out the non-static private key. It was generated through the part in which I commented on the use of "non-static secret key usage". I also commented out the lines of code of signed messages (at the bottom of the code) because they were shown in the tutorial, which is not important for key / address generation. I also tried to "decorate" the code a bit by placing prints, etc. Only at the bottom of the file and sorting a few things, etc., but it turned out that Python 2.7 didn't like it.

I am using Python 2.7, everything is installed successfully, the code works as it is now, with parts commented out. I checked the results printed with bitaddress.org the same as the bootloader from the tutorial. Tried searching to find a solution, but I couldn't get anything useful from the search results.

If you could help me with a few missing lines of code, I'd be happy! Also maybe explain / comment on the code what to do. Especially for the still missing BIP38 Privkey password encryption. So I can understand what and what can understand.

Running the .py script returns valid results except for the 80 bytes I added - no idea if this was fixed by me. Adding 80 bytes is a necessary step to get the final private key, starting at "5" later.

Start printing:

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

      

Here you can see my code commented here and there as far as I could, according to the tutorial: (Forgot to comment "This is my hashed external key checksum", sorry for the confusion. This is the code I need now.)

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 = ('\04' + 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 = ('\00') + 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")

      

+3


source to share


1 answer


What you probably misunderstood from the Bitcoin Wiki steps is that all hashing and stuff should be done on the keys as bytes , not strings.

This means that if you want to get the WIF key from the private key "29a59..."

, you don't need to hash the string "8029a59..."

but the binary data that matches it.

A snippet is missing here that works



# 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 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)

      

where binascii.unhexlify(...)

tells us the binary data, represented as a hex string.

The rest of your code works just fine;)

+4


source







All Articles