<p>You need to convert string hex to bytes hex format before feeding it to <code>b58encode</code> to produce <code>C6t2iJ7AXA2X1KQVnqw3r7NKtKaERdLnaGmbDZNqxXjk</code>.</p>
<pre><code>import base58
    
privatekey_base58 = base58.b58encode(bytes.fromhex(
    &quot;a4f228d49910e8ecb53ba6f23f33fbfd2bad442e902ea20b8cf89c473237bf9f&quot;
))
</code></pre>
<p>The tutorial you linked to is not accessible anymore, so I am not sure whether they talked about it there, but there are actually several steps between generation private key and conversion to Wallet Import Format (WIF). You can see more details about it at <a href="https://en.bitcoin.it/wiki/Wallet_import_format" rel="nofollow noreferrer">https://en.bitcoin.it/wiki/Wallet_import_format</a>. According to the wiki page, you need to extend private key with <code>0x80</code> (for mainnet addresses). Extended private key is then passed through double <code>sha256</code> to extract a checksum (first 4 bytes). Finally, extended private key and checksum are concatenated and Base58 check encoding is applied to produce WIF private key. Surprisingly enough, their tutorial does not use Base58 check encoding, but Base58 encoding.</p>

CC BY-SA 4.0
2022-04-26T05:43:06.323Z
2022-04-26T05:43:06.323Z
martinkersner
<p>Use b58encode_check instead of non-check version and convert your hex to binary before passing it to the library.</p>

CC BY-SA 4.0
2021-10-10T12:04:04.387Z
And how do i decode base58 string ? Should i turn the string to binary too before decoding ?
i'm ashamed with what i asked
CC BY-SA 4.0
2021-10-10T12:23:24.140Z
No, but to decode convert the decode result to hex because it'll be in binary
MCCCS
CC BY-SA 4.0
2021-10-11T02:34:46.890Z
help it doesnt work , i tried base58.b58encode_check(bin(int("0x000c2c910a661178ef63e276dd0e239883b862f58cc3c0439f", 16))) but it doesnt gives 127NVqnjf8gB9BFAW2dnQeM6wqmy1gbGtv like in the tutorial
i'm ashamed with what i asked
CC BY-SA 4.0
2021-10-11T06:23:39.820Z
Does this give you any inspiration https://stackoverflow.com/a/23565829 ?
MCCCS
CC BY-SA 4.0
2021-10-10T11:26:25.210Z
2021-10-10T11:26:25.210Z
MCCCS
<p><strong>As of Python 3.10.8</strong></p>
<p>Here's how to derive the addresses from 3 randomly generated private keys from <a href="https://www.bitaddress.org/" rel="nofollow noreferrer">bitaddress.org</a>.</p>
<p>Example Bitcoin addresses with private keys:</p>
<ol>
<li>Private Key: L5Mssn1ANiFXuWrYpSohHfbvZzuUNZ7Px8x4vCLCFthihhEVwowM<br>
Address: 1FbFJHvT3xE2i5TDqtyCUuCiAjVJMV9XPt</li>
<li>Private Key: L3jg9jj7SBfoU5qiLunjuES1f6aoSjvQMYBXHqR4b7HBv92dnHsq<br>
Address: 1PSds68vNzCeYvJNB6axnN8VnrLSnJC6S1</li>
<li>Private Key: KwmT38RYZe55mM1TjY8dy41VpzerunJMoLt4Z97tF33rxHUsejLT<br>
Address: 1GPqjz4qQxz7ZWnvSN5Gc2H5hkhd5va95i</li>
</ol>
<p>In the shell:</p>
<pre><code>pip install ecdsa base58 hashlib
</code></pre>
<p>In Python:</p>
<pre><code>import ecdsa
import hashlib
import base58

# These are the 3 private keys in base58check encoding.
privkey_b58_1 = &quot;L5Mssn1ANiFXuWrYpSohHfbvZzuUNZ7Px8x4vCLCFthihhEVwowM&quot;
privkey_b58_2 = &quot;L3jg9jj7SBfoU5qiLunjuES1f6aoSjvQMYBXHqR4b7HBv92dnHsq&quot;
privkey_b58_3 = &quot;KwmT38RYZe55mM1TjY8dy41VpzerunJMoLt4Z97tF33rxHUsejLT&quot;

# Remove the \x80 version prefix and x\01 compression suffix.
privkey_bin_1 = base58.b58decode_check(privkey_b58_1.encode())[1:-1]
privkey_bin_2 = base58.b58decode_check(privkey_b58_2.encode())[1:-1]
privkey_bin_3 = base58.b58decode_check(privkey_b58_3.encode())[1:-1]

# Create signing keys using the SECP256k1 curve in ECDSA.
sk_bin_1 = ecdsa.SigningKey.from_string(privkey_bin_1, ecdsa.SECP256k1)
sk_bin_2 = ecdsa.SigningKey.from_string(privkey_bin_2, ecdsa.SECP256k1)
sk_bin_3 = ecdsa.SigningKey.from_string(privkey_bin_3, ecdsa.SECP256k1)

# Derive verifying keys from the signing keys.
vk_bin_1 = sk_bin_1.verifying_key.to_string()
vk_bin_2 = sk_bin_2.verifying_key.to_string()
vk_bin_3 = sk_bin_3.verifying_key.to_string()

# Determine if the Y value is even. This is required for compression.
vk_iseven_1 = int(vk_bin_1.hex(), base=16) % 2 == 0
vk_iseven_2 = int(vk_bin_2.hex(), base=16) % 2 == 0
vk_iseven_3 = int(vk_bin_3.hex(), base=16) % 2 == 0

# Determine the prefix for the X value based on whether the Y value is even.
vk_prefix_1 = b&quot;\x02&quot; if vk_iseven_1 else b&quot;\x03&quot;
vk_prefix_2 = b&quot;\x02&quot; if vk_iseven_2 else b&quot;\x03&quot;
vk_prefix_3 = b&quot;\x02&quot; if vk_iseven_3 else b&quot;\x03&quot;

# Extract the X value from the verifying key. X is the first 32 bytes.
vk_xval_1 = vk_bin_1[:32]
vk_xval_2 = vk_bin_2[:32]
vk_xval_3 = vk_bin_3[:32]

# Get the SHA256 hash of the X value with the even/odd prefix.
vk_sha256_1 = hashlib.sha256(vk_prefix_1 + vk_xval_1).digest()
vk_sha256_2 = hashlib.sha256(vk_prefix_2 + vk_xval_2).digest()
vk_sha256_3 = hashlib.sha256(vk_prefix_3 + vk_xval_3).digest()

# Get the RIPEMD-160 hash of the SHA256 hash, then add the address prefix.
ripemd160_1 = hashlib.new(&quot;ripemd160&quot;)
ripemd160_1.update(vk_sha256_1)
address_1 = b&quot;\x00&quot; + ripemd160_1.digest()

ripemd160_2 = hashlib.new(&quot;ripemd160&quot;)
ripemd160_2.update(vk_sha256_2)
address_2 = b&quot;\x00&quot; + ripemd160_2.digest()

ripemd160_3 = hashlib.new(&quot;ripemd160&quot;)
ripemd160_3.update(vk_sha256_3)
address_3 = b&quot;\x00&quot; + ripemd160_3.digest()

# Get the base58check encoding for each address.
address_b58_1 = base58.b58encode_check(address_1)
address_b58_2 = base58.b58encode_check(address_2)
address_b58_3 = base58.b58encode_check(address_3)

# Show the addresses.
for x in [address_b58_1, address_b58_2, address_b58_3]:
    print(x.decode())

# 1FbFJHvT3xE2i5TDqtyCUuCiAjVJMV9XPt
# 1PSds68vNzCeYvJNB6axnN8VnrLSnJC6S1
# 1GPqjz4qQxz7ZWnvSN5Gc2H5hkhd5va95i
</code></pre>

CC BY-SA 4.0
2022-11-08T16:27:36.367Z
2023-05-03T16:29:33.020Z
2023-05-03T16:29:33.020Z
Tyler Pantuso
<p>I was following the tutorial here : <a href="https://hackernoon.com/how-to-generate-bitcoin-addresses-technical-address-generation-explanation-rus3z9e" rel="nofollow noreferrer">https://hackernoon.com/how-to-generate-bitcoin-addresses-technical-address-generation-explanation-rus3z9e</a></p>
<p>i imported <a href="https://pypi.org/project/base58/" rel="nofollow noreferrer">base58</a> to my python project :</p>
<pre><code>import base58
</code></pre>
<p>I tried to convert the private key at the tutorial into the base58 version</p>
<pre><code>privatekey = &quot;a4f228d49910e8ecb53ba6f23f33fbfd2bad442e902ea20b8cf89c473237bf9f&quot;

# expected : C6t2iJ7AXA2X1KQVnqw3r7NKtKaERdLnaGmbDZNqxXjk
privatekey_base58 = base58.b58encode(privatekey)
</code></pre>
<p>But it didn't give me the expected value like in the tutorial , instead it gives me this
<a href="https://i.sstatic.net/z8q56.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/z8q56.png" alt="enter image description here" /></a></p>
<p>How do i properly encode a string to base58 and decode base58 to original string ?</p>

<python><base58>
How do i properly encode and decode base58 in python?
i'm ashamed with what i asked
# How do i properly encode and decode base58 in python?

(Asked by: username_0 on 2021-10-10)

I was following the tutorial here : https://hackernoon.com/how-to-generate-bitcoin-addresses-technical-address-generation-explanation-rus3z9e
i imported base58 to my python project :
import base58

I tried to convert the private key at the tutorial into the base58 version
privatekey = "a4f228d49910e8ecb53ba6f23f33fbfd2bad442e902ea20b8cf89c473237bf9f"

# expected : C6t2iJ7AXA2X1KQVnqw3r7NKtKaERdLnaGmbDZNqxXjk
privatekey_base58 = base58.b58encode(privatekey)

But it didn't give me the expected value like in the tutorial , instead it gives me this

How do i properly encode a string to base58 and decode base58 to original string ?

**Tags:** python, base58


---

## 3 answers

### Answer by username_1 on 2022-04-26. Score: 3

You need to convert string hex to bytes hex format before feeding it to b58encode to produce C6t2iJ7AXA2X1KQVnqw3r7NKtKaERdLnaGmbDZNqxXjk.
import base58
    
privatekey_base58 = base58.b58encode(bytes.fromhex(
    "a4f228d49910e8ecb53ba6f23f33fbfd2bad442e902ea20b8cf89c473237bf9f"
))

The tutorial you linked to is not accessible anymore, so I am not sure whether they talked about it there, but there are actually several steps between generation private key and conversion to Wallet Import Format (WIF). You can see more details about it at https://en.bitcoin.it/wiki/Wallet_import_format. According to the wiki page, you need to extend private key with 0x80 (for mainnet addresses). Extended private key is then passed through double sha256 to extract a checksum (first 4 bytes). Finally, extended private key and checksum are concatenated and Base58 check encoding is applied to produce WIF private key. Surprisingly enough, their tutorial does not use Base58 check encoding, but Base58 encoding.


---

### Answer by username_2 on 2021-10-10. Score: 1

Use b58encode\_check instead of non-check version and convert your hex to binary before passing it to the library.

> **Comments:**
> **username_0**: And how do i decode base58 string ? Should i turn the string to binary too before decoding ?  
> **username_2**: No, but to decode convert the decode result to hex because it'll be in binary  
> **username_0**: help it doesnt work , i tried base58.b58encode_check(bin(int("0x000c2c910a661178ef63e276dd0e239883b862f58cc3c0439f", 16))) but it doesnt gives 127NVqnjf8gB9BFAW2dnQeM6wqmy1gbGtv like in the tutorial  
> **username_2**: Does this give you any inspiration https://stackoverflow.com/a/23565829 ?  

---

### Answer by username_3 on 2022-11-08. Score: -1

As of Python 3.10.8
Here's how to derive the addresses from 3 randomly generated private keys from bitaddress.org.
Example Bitcoin addresses with private keys:

Private Key: L5Mssn1ANiFXuWrYpSohHfbvZzuUNZ7Px8x4vCLCFthihhEVwowM
Address: 1FbFJHvT3xE2i5TDqtyCUuCiAjVJMV9XPt
Private Key: L3jg9jj7SBfoU5qiLunjuES1f6aoSjvQMYBXHqR4b7HBv92dnHsq
Address: 1PSds68vNzCeYvJNB6axnN8VnrLSnJC6S1
Private Key: KwmT38RYZe55mM1TjY8dy41VpzerunJMoLt4Z97tF33rxHUsejLT
Address: 1GPqjz4qQxz7ZWnvSN5Gc2H5hkhd5va95i

In the shell:
pip install ecdsa base58 hashlib

In Python:
import ecdsa
import hashlib
import base58

# These are the 3 private keys in base58check encoding.
privkey_b58_1 = "L5Mssn1ANiFXuWrYpSohHfbvZzuUNZ7Px8x4vCLCFthihhEVwowM"
privkey_b58_2 = "L3jg9jj7SBfoU5qiLunjuES1f6aoSjvQMYBXHqR4b7HBv92dnHsq"
privkey_b58_3 = "KwmT38RYZe55mM1TjY8dy41VpzerunJMoLt4Z97tF33rxHUsejLT"

# Remove the \x80 version prefix and x\01 compression suffix.
privkey_bin_1 = base58.b58decode_check(privkey_b58_1.encode())[1:-1]
privkey_bin_2 = base58.b58decode_check(privkey_b58_2.encode())[1:-1]
privkey_bin_3 = base58.b58decode_check(privkey_b58_3.encode())[1:-1]

# Create signing keys using the SECP256k1 curve in ECDSA.
sk_bin_1 = ecdsa.SigningKey.from_string(privkey_bin_1, ecdsa.SECP256k1)
sk_bin_2 = ecdsa.SigningKey.from_string(privkey_bin_2, ecdsa.SECP256k1)
sk_bin_3 = ecdsa.SigningKey.from_string(privkey_bin_3, ecdsa.SECP256k1)

# Derive verifying keys from the signing keys.
vk_bin_1 = sk_bin_1.verifying_key.to_string()
vk_bin_2 = sk_bin_2.verifying_key.to_string()
vk_bin_3 = sk_bin_3.verifying_key.to_string()

# Determine if the Y value is even. This is required for compression.
vk_iseven_1 = int(vk_bin_1.hex(), base=16) % 2 == 0
vk_iseven_2 = int(vk_bin_2.hex(), base=16) % 2 == 0
vk_iseven_3 = int(vk_bin_3.hex(), base=16) % 2 == 0

# Determine the prefix for the X value based on whether the Y value is even.
vk_prefix_1 = b"\x02" if vk_iseven_1 else b"\x03"
vk_prefix_2 = b"\x02" if vk_iseven_2 else b"\x03"
vk_prefix_3 = b"\x02" if vk_iseven_3 else b"\x03"

# Extract the X value from the verifying key. X is the first 32 bytes.
vk_xval_1 = vk_bin_1[:32]
vk_xval_2 = vk_bin_2[:32]
vk_xval_3 = vk_bin_3[:32]

# Get the SHA256 hash of the X value with the even/odd prefix.
vk_sha256_1 = hashlib.sha256(vk_prefix_1 + vk_xval_1).digest()
vk_sha256_2 = hashlib.sha256(vk_prefix_2 + vk_xval_2).digest()
vk_sha256_3 = hashlib.sha256(vk_prefix_3 + vk_xval_3).digest()

# Get the RIPEMD-160 hash of the SHA256 hash, then add the address prefix.
ripemd160_1 = hashlib.new("ripemd160")
ripemd160_1.update(vk_sha256_1)
address_1 = b"\x00" + ripemd160_1.digest()

ripemd160_2 = hashlib.new("ripemd160")
ripemd160_2.update(vk_sha256_2)
address_2 = b"\x00" + ripemd160_2.digest()

ripemd160_3 = hashlib.new("ripemd160")
ripemd160_3.update(vk_sha256_3)
address_3 = b"\x00" + ripemd160_3.digest()

# Get the base58check encoding for each address.
address_b58_1 = base58.b58encode_check(address_1)
address_b58_2 = base58.b58encode_check(address_2)
address_b58_3 = base58.b58encode_check(address_3)

# Show the addresses.
for x in [address_b58_1, address_b58_2, address_b58_3]:
    print(x.decode())

# 1FbFJHvT3xE2i5TDqtyCUuCiAjVJMV9XPt
# 1PSds68vNzCeYvJNB6axnN8VnrLSnJC6S1
# 1GPqjz4qQxz7ZWnvSN5Gc2H5hkhd5va95i


---

