<p>The address is <em>already</em> a hash, together with a 4-byte checksum and a version byte.  To get from an address to a hash160, you don't have to compute sha256 or ripemd160 of anything.  You just have to decode it from base58 back to hex, and discard the unwanted junk.</p>

<p>If you take <code>mvm74FACaagz94rjWbNmW2EmhJdmEGcxpa</code> and base58 decode, you get</p>

<pre><code> 6FA73706385FFFBF18855F2AEE2A6168F29DBB597EF59C240B
 VVxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxSSSSSSSS
</code></pre>

<p>The first byte (6F) is the version byte; discard it.  The last 4 bytes are the checksum; discard it.  The remaining 20 bytes are the hash160 of the public key corresponding to the address.</p>

CC BY-SA 3.0
2017-09-20T21:29:38.483Z
2017-09-20T21:29:38.483Z
Nate Eldredge
<p>I have already answered this question on <a href="https://stackoverflow.com/questions/46328870/getting-hash160-bitcoin-address-in-python/46333720#46333720">StackOverflow</a>, but I guess I'll just repost the answer here.</p>

<p>Finally I've made it.
Some revelations in my answer may look obvious and basic to you, but I hope they'll be helpful to the people that are completely new to Bitcoin (such as me).</p>

<hr>

<p><a href="https://stackoverflow.com/questions/46328870/getting-hash160-bitcoin-address-in-python/46333720#46333720">Wiki</a> says that I can get Hash160 by reversing last step of address production</p>

<p><a href="https://i.sstatic.net/cfYqE.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/cfYqE.png" alt="enter image description here"></a>
(Hash160 is higlighted)</p>

<p>This step is encoding a byte string with base58 alphabet</p>

<pre><code>b58 = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
</code></pre>

<p>This alphabet lacks 0, I, l, O, as these symbols are easy to mix up. And that's the last thing you want to do when one wrong symbol may lead to losing a fat amount of money.</p>

<p>Thus, we need to turn <code>mvm74FACaagz94rjWbNmW2EmhJdmEGcxpa</code> into a byte-string. Bytes go in hexadecimal format and may range from <code>0x00</code> (0 decimal) to <code>0xff</code> (255 decimal).
And mind that we have a special b58 alphabet to deal with: decoding the address with utf-8 or other encoding standards will yield nonsense.</p>

<p>At first I thought that I can easily decode the address with this function:</p>

<pre><code>def decode(addr):
    b58 = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
    decoded = ''
    for i in addr:
        temp = hex(b58.index(i))
        if len(temp) == 3:
            temp = '0' + temp[-1]
        else:
            temp = temp[2:]
        decoded += (temp)
    return (decoded)

decode('mvm74FACaagz94rjWbNmW2EmhJdmEGcxpa')

&gt;&gt; '2c352c06030e090b212127390803312a1d22152c1d010d2c2811242c0d0f23372f21'
</code></pre>

<p>But the result is nothing like the hash I looked up in the transaction (<code>a73706385fffbf18855f2aee2a6168f29dbb597e</code>). This way I learned I had no idea how decoding is done. What if Hash160 has <code>0xff</code> ? There's no such symbol in b58, as 58 in hex is just <code>0x3a</code>. While decoding b58 we can't treat each symbol independently. The whole address makes up one  giant number written in base58 numerical system (its first digit corresponds to 58**34).</p>

<p>To get the byte string I first turned this number into a decimal and only then in byte-string.</p>

<p><em>If you know how to avoid this detour and get bytes directly -- please comment</em></p>

<pre><code>def decode(addr):

    b58 = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'

    def base58_to_dec(addr):
        dec = 0
        for i in range(len(addr)):
            dec = int(dec * 58 + b58.index(addr[i]))
        print('Decimal representation')
        print(dec)
        return(dec)

    def dec_to_byte(dec):
        out = ''
        while dec != 0:
            print(dec)
            remn = dec % 256
            dec = int((dec - remn) / 256)
            temp = hex(remn)
            if len(temp) == 3:
                temp = '0' + temp[-1]
            else:
                temp = temp[2:]
            out = temp + out
        return(out)

    dec = base58_to_dec(addr)
    out = dec_to_byte(dec)
    return (out)

decode("mvm74FACaagz94rjWbNmW2EmhJdmEGcxpa")
&gt;&gt; Decimal representation
&gt;&gt; 700858390993795610399098743129153130886272689085970101576715
&gt;&gt; '6fa7370638600000000000000000000000000000000000000b'
</code></pre>

<p>That output looks somewhat like what I need (<code>a7370638...</code>) but has way too many zeroes. Don't look that the first byte (<code>6f</code>) doesn't match: it has nothing to do with Hash160 we need, just protocol version.</p>

<p>This is likely a precision error. To deal with it, I used <code>mpmath</code> which lets you operate with integers precisely. </p>

<pre><code>import mpmath as mp
mp.dps = 1000

def decode(addr):

    b58 = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'

    def base58_to_dec(addr):
        dec = 0
        for i in range(len(addr)):
            dec = int(dec * 58 + b58.index(addr[i]))
        return(dec)

    def dec_to_byte(dec):
        out = ''
        while dec != 0:
            remn = mp.mpf(dec % 256)
            dec = mp.mpf((dec - remn) / 256)
            temp = hex(int(remn))
            if len(temp) == 3:
                temp = '0' + temp[-1]
            else:
                temp = temp[2:]
            out = temp + out

        return (out)

    dec = base58_to_dec(addr)
    out = dec_to_byte(dec)
    return (out)
</code></pre>

<p>Apply precise modulo operation and we can finally get the Hash160. Just make sure you trip the first and last 4 bytes that carry fat-finger check.</p>

<pre><code>x = decode('mvm74FACaagz94rjWbNmW2EmhJdmEGcxpa')
print(x)
&gt;&gt; 6fa73706385fffbf18855f2aee2a6168f29dbb597ef59c240b

print(x[2:-8])
&gt;&gt; a73706385fffbf18855f2aee2a6168f29dbb597e
</code></pre>

<p>Yay! Just like in the transaction!</p>

CC BY-SA 4.0
2022-02-23T23:18:41.283Z
I've tested the last code example and it prints the wrong value. `print(decode('mvm74FACaagz94rjWbNmW2EmhJdmEGcxpa'))` prints `6fa7370638600000000000000000000000000000000000000b` instead of `6fa73706385fffbf18855f2aee2a6168f29dbb597ef59c240b` (Python 3).
kenorb
CC BY-SA 3.0
2017-09-21T00:58:41.227Z
2017-10-11T05:32:58.653Z
2017-10-11T05:32:58.653Z
lotrus28
<p>Install <code>base58</code> package (Ubuntu: <code>sudo apt-get install base58</code>) then run the following:</p>
<pre><code>$ printf mvm74FACaagz94rjWbNmW2EmhJdmEGcxpa | base58 -d | xxd -p
6fa73706385fffbf18855f2aee2a6168f29dbb597ef59c240b
</code></pre>
<p>To decode into address, use:</p>
<pre><code>$ printf mvm74FACaagz94rjWbNmW2EmhJdmEGcxpa | base58 -d | cut -c2- | xxd -p | head -c40
a73706385fffbf18855f2aee2a6168f29dbb597e
</code></pre>

CC BY-SA 4.0
2022-02-23T22:42:23.590Z
2022-02-23T22:42:23.590Z
kenorb
<h3>Python 3</h3>
<p>Install base58 (<code>pip3 install base58</code>) and use the following code:</p>
<pre><code>import base58
print(base58.b58decode_check(b'mvm74FACaagz94rjWbNmW2EmhJdmEGcxpa').hex()[2:])
</code></pre>
<p>One-liner:</p>
<pre><code>$ echo 'import base58; print(base58.b58decode_check(b&quot;mvm74FACaagz94rjWbNmW2EmhJdmEGcxpa&quot;).hex()[2:])' | python3
a73706385fffbf18855f2aee2a6168f29dbb597e
</code></pre>
<p>Script to convert file with list of addresses to the corresponding hashes:</p>
<pre><code>while read addr; do python3 -c &quot;import base58; print(base58.b58decode_check(b'$addr').hex()[2:])&quot;; done &lt; btc.csv &gt; btc.hash
</code></pre>

CC BY-SA 4.0
2022-02-23T23:31:27.620Z
2022-02-23T23:38:10.797Z
2022-02-23T23:38:10.797Z
kenorb
<p><strong>tl;dr</strong>
How should one perform Hash160, using most basic tools?</p>

<p>====================================================</p>

<p>Hi,</p>

<p>I'm trying to figure out, how transactions work in bitcoin.</p>

<p>When I choose inputs for a new tx I want to make sure they belong to a specific address. However, existing txs do not specify previous outputs' addresses, but instead they contain address' hashes.</p>

<p>e.g.: </p>

<pre><code>&gt;&gt; bx fetch-tx 11a1b7ac0a65bd50b7094c720aecd77cfd83d84b1707960fd00dd82a888aab5c --config /home/theo/Desktop/bx-testnet.cfg

{
    hash 11a1b7ac0a65bd50b7094c720aecd77cfd83d84b1707960fd00dd82a888aab5c
    inputs
    {
        input
        {
            address_hash f3b7278583827a049d6be894bf7f516178a0c8e6
            previous_output
            {
                hash 4a3532061d43086299ae9b2409a456bb9638dff32e0858c4ccda27203fb2e4f6
                index 1
            }
            script "[30440220146b8b5b014245a9e27e21122d4dded04c3f39c3a49ac2494743d6f6ae8efff602206d417a4be9c7431ea69699132438510ade1cf8d746607f77d114907762ed1eb301] [023dd2e892290e41bb78efce6ea30a97015ef13eaaa9ebb7b0514485fc365cc391]"
            sequence 4294967295
        }
    }
    lock_time 0
    outputs
    {
        output
        {
            address_hash a73706385fffbf18855f2aee2a6168f29dbb597e
            script "dup hash160 [a73706385fffbf18855f2aee2a6168f29dbb597e] equalverify checksig"
            value 130000000
        }
        output
        {
            address_hash ad6e80394af99ece5d7701bf2f457480b93965b7
            script "dup hash160 [ad6e80394af99ece5d7701bf2f457480b93965b7] equalverify checksig"
            value 49525957813
        }
    }
    version 1
}
</code></pre>

<p>Say, I want to check which of the outputs can be sent from address <code>mvm74FACaagz94rjWbNmW2EmhJdmEGcxpa</code>
So I take its Hash160 in Python:</p>

<pre><code>&gt;&gt; hashlib.new('ripemd160', hashlib.sha256("mvm74FACaagz94rjWbNmW2EmhJdmEGcxpa".encode('utf-8')).digest()).hexdigest()
'748598cd9b004aecf8a2d97464fb1f2a90562ffe'
</code></pre>

<p>That is not the result I expected: <code>a73706385fffbf18855f2aee2a6168f29dbb597e</code></p>

<p>Meanwhile, <a href="http://bitcoinvalued.com/tools.php" rel="nofollow noreferrer">this</a> online service calculates hash correctly.</p>

<p>How do I Hash160 a bitcoin address, preferably in Python?</p>

CC BY-SA 3.0
2017-09-20T20:48:53.270Z
while I can't help with python, you may want to look at "http://www.righto.com/2014/02/bitcoins-hard-way-using-raw-bitcoin.html", it has good explanation. Also I'm not sure if I understand  your logic with the addresses to spend from. You would use the UTXOs from previous transactions... So I'd use "listunspent" in the core wallet, to see the prev tx ID and the vout, to use in a new (unsigned) transaction. An address hash cannot be reversed easily, that's why we have hash functions. Easy to go into one direction, impossible to reverse. That gives us the security in the whole bitcoin network.
pebwindkraft
CC BY-SA 3.0
2017-09-20T20:52:22.427Z
@pebwindkraft But I need the script in previous output to sign, don't I? Also, seems to me I got the encoding idea wrong. Hash160 clearly has bytes bigger than 3a (58 decimal), so my decoding function is nonsense
lotrus28
CC BY-SA 3.0
2017-09-20T21:05:00.890Z
yes, you give it the scriptPubKey, see the meanwhile famous 19step example, and some python at the end: here: https://bitcoin.stackexchange.com/questions/3374/how-to-redeem-a-basic-tx
pebwindkraft
<address><hash><testnet><python>
How to produce a Hash160 bitcoin address?
lotrus28
# How to produce a Hash160 bitcoin address?

(Asked by: username_0 on 2017-09-20)

**tl;dr**
How should one perform Hash160, using most basic tools?

====================================================

Hi,

I'm trying to figure out, how transactions work in bitcoin.

When I choose inputs for a new tx I want to make sure they belong to a specific address. However, existing txs do not specify previous outputs' addresses, but instead they contain address' hashes.

e.g.:

```
>> bx fetch-tx 11a1b7ac0a65bd50b7094c720aecd77cfd83d84b1707960fd00dd82a888aab5c --config /home/theo/Desktop/bx-testnet.cfg

{
    hash 11a1b7ac0a65bd50b7094c720aecd77cfd83d84b1707960fd00dd82a888aab5c
    inputs
    {
        input
        {
            address_hash f3b7278583827a049d6be894bf7f516178a0c8e6
            previous_output
            {
                hash 4a3532061d43086299ae9b2409a456bb9638dff32e0858c4ccda27203fb2e4f6
                index 1
            }
            script "[30440220146b8b5b014245a9e27e21122d4dded04c3f39c3a49ac2494743d6f6ae8efff602206d417a4be9c7431ea69699132438510ade1cf8d746607f77d114907762ed1eb301] [023dd2e892290e41bb78efce6ea30a97015ef13eaaa9ebb7b0514485fc365cc391]"
            sequence 4294967295
        }
    }
    lock_time 0
    outputs
    {
        output
        {
            address_hash a73706385fffbf18855f2aee2a6168f29dbb597e
            script "dup hash160 [a73706385fffbf18855f2aee2a6168f29dbb597e] equalverify checksig"
            value 130000000
        }
        output
        {
            address_hash ad6e80394af99ece5d7701bf2f457480b93965b7
            script "dup hash160 [ad6e80394af99ece5d7701bf2f457480b93965b7] equalverify checksig"
            value 49525957813
        }
    }
    version 1
}

```

Say, I want to check which of the outputs can be sent from address `mvm74FACaagz94rjWbNmW2EmhJdmEGcxpa`
So I take its Hash160 in Python:

```
>> hashlib.new('ripemd160', hashlib.sha256("mvm74FACaagz94rjWbNmW2EmhJdmEGcxpa".encode('utf-8')).digest()).hexdigest()
'748598cd9b004aecf8a2d97464fb1f2a90562ffe'

```

That is not the result I expected: `a73706385fffbf18855f2aee2a6168f29dbb597e`

Meanwhile, [this](http://bitcoinvalued.com/tools.php) online service calculates hash correctly.

How do I Hash160 a bitcoin address, preferably in Python?

**Tags:** address, hash, testnet, python

> **Comments:**
> **username_1**: while I can't help with python, you may want to look at "http://www.righto.com/2014/02/bitcoins-hard-way-using-raw-bitcoin.html", it has good explanation. Also I'm not sure if I understand  your logic with the addresses to spend from. You would use the UTXOs from previous transactions... So I'd use "listunspent" in the core wallet, to see the prev tx ID and the vout, to use in a new (unsigned) transaction. An address hash cannot be reversed easily, that's why we have hash functions. Easy to go into one direction, impossible to reverse. That gives us the security in the whole bitcoin network.  
> **username_0**: @username_1 But I need the script in previous output to sign, don't I? Also, seems to me I got the encoding idea wrong. Hash160 clearly has bytes bigger than 3a (58 decimal), so my decoding function is nonsense  
> **username_1**: yes, you give it the scriptPubKey, see the meanwhile famous 19step example, and some python at the end: here: https://bitcoin.stackexchange.com/questions/3374/how-to-redeem-a-basic-tx  

---

## 4 answers

### Answer by username_2 on 2017-09-20. Score: 4

The address is *already* a hash, together with a 4-byte checksum and a version byte. To get from an address to a hash160, you don't have to compute sha256 or ripemd160 of anything. You just have to decode it from base58 back to hex, and discard the unwanted junk.

If you take `mvm74FACaagz94rjWbNmW2EmhJdmEGcxpa` and base58 decode, you get

```
 6FA73706385FFFBF18855F2AEE2A6168F29DBB597EF59C240B
 VVxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxSSSSSSSS

```

The first byte (6F) is the version byte; discard it. The last 4 bytes are the checksum; discard it. The remaining 20 bytes are the hash160 of the public key corresponding to the address.


---

### Answer by username_0 on 2017-09-21. Score: 1

I have already answered this question on [StackOverflow](https://stackoverflow.com/questions/46328870/getting-hash160-bitcoin-address-in-python/46333720#46333720), but I guess I'll just repost the answer here.

Finally I've made it.
Some revelations in my answer may look obvious and basic to you, but I hope they'll be helpful to the people that are completely new to Bitcoin (such as me).

---

[Wiki](https://stackoverflow.com/questions/46328870/getting-hash160-bitcoin-address-in-python/46333720#46333720) says that I can get Hash160 by reversing last step of address production

[![enter image description here](https://i.sstatic.net/cfYqE.png)](https://i.sstatic.net/cfYqE.png)
(Hash160 is higlighted)

This step is encoding a byte string with base58 alphabet

```
b58 = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'

```

This alphabet lacks 0, I, l, O, as these symbols are easy to mix up. And that's the last thing you want to do when one wrong symbol may lead to losing a fat amount of money.

Thus, we need to turn `mvm74FACaagz94rjWbNmW2EmhJdmEGcxpa` into a byte-string. Bytes go in hexadecimal format and may range from `0x00` (0 decimal) to `0xff` (255 decimal).
And mind that we have a special b58 alphabet to deal with: decoding the address with utf-8 or other encoding standards will yield nonsense.

At first I thought that I can easily decode the address with this function:

```
def decode(addr):
    b58 = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
    decoded = ''
    for i in addr:
        temp = hex(b58.index(i))
        if len(temp) == 3:
            temp = '0' + temp[-1]
        else:
            temp = temp[2:]
        decoded += (temp)
    return (decoded)

decode('mvm74FACaagz94rjWbNmW2EmhJdmEGcxpa')

>> '2c352c06030e090b212127390803312a1d22152c1d010d2c2811242c0d0f23372f21'

```

But the result is nothing like the hash I looked up in the transaction (`a73706385fffbf18855f2aee2a6168f29dbb597e`). This way I learned I had no idea how decoding is done. What if Hash160 has `0xff` ? There's no such symbol in b58, as 58 in hex is just `0x3a`. While decoding b58 we can't treat each symbol independently. The whole address makes up one giant number written in base58 numerical system (its first digit corresponds to 58\*\*34).

To get the byte string I first turned this number into a decimal and only then in byte-string.

*If you know how to avoid this detour and get bytes directly -- please comment*

```
def decode(addr):

    b58 = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'

    def base58_to_dec(addr):
        dec = 0
        for i in range(len(addr)):
            dec = int(dec * 58 + b58.index(addr[i]))
        print('Decimal representation')
        print(dec)
        return(dec)

    def dec_to_byte(dec):
        out = ''
        while dec != 0:
            print(dec)
            remn = dec % 256
            dec = int((dec - remn) / 256)
            temp = hex(remn)
            if len(temp) == 3:
                temp = '0' + temp[-1]
            else:
                temp = temp[2:]
            out = temp + out
        return(out)

    dec = base58_to_dec(addr)
    out = dec_to_byte(dec)
    return (out)

decode("mvm74FACaagz94rjWbNmW2EmhJdmEGcxpa")
>> Decimal representation
>> 700858390993795610399098743129153130886272689085970101576715
>> '6fa7370638600000000000000000000000000000000000000b'

```

That output looks somewhat like what I need (`a7370638...`) but has way too many zeroes. Don't look that the first byte (`6f`) doesn't match: it has nothing to do with Hash160 we need, just protocol version.

This is likely a precision error. To deal with it, I used `mpmath` which lets you operate with integers precisely.

```
import mpmath as mp
mp.dps = 1000

def decode(addr):

    b58 = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'

    def base58_to_dec(addr):
        dec = 0
        for i in range(len(addr)):
            dec = int(dec * 58 + b58.index(addr[i]))
        return(dec)

    def dec_to_byte(dec):
        out = ''
        while dec != 0:
            remn = mp.mpf(dec % 256)
            dec = mp.mpf((dec - remn) / 256)
            temp = hex(int(remn))
            if len(temp) == 3:
                temp = '0' + temp[-1]
            else:
                temp = temp[2:]
            out = temp + out

        return (out)

    dec = base58_to_dec(addr)
    out = dec_to_byte(dec)
    return (out)

```

Apply precise modulo operation and we can finally get the Hash160. Just make sure you trip the first and last 4 bytes that carry fat-finger check.

```
x = decode('mvm74FACaagz94rjWbNmW2EmhJdmEGcxpa')
print(x)
>> 6fa73706385fffbf18855f2aee2a6168f29dbb597ef59c240b

print(x[2:-8])
>> a73706385fffbf18855f2aee2a6168f29dbb597e

```

Yay! Just like in the transaction!

> **Comments:**
> **username_3**: I've tested the last code example and it prints the wrong value. `print(decode('mvm74FACaagz94rjWbNmW2EmhJdmEGcxpa'))` prints `6fa7370638600000000000000000000000000000000000000b` instead of `6fa73706385fffbf18855f2aee2a6168f29dbb597ef59c240b` (Python 3).  

---

### Answer by username_3 on 2022-02-23. Score: 0

Install `base58` package (Ubuntu: `sudo apt-get install base58`) then run the following:

```
$ printf mvm74FACaagz94rjWbNmW2EmhJdmEGcxpa | base58 -d | xxd -p
6fa73706385fffbf18855f2aee2a6168f29dbb597ef59c240b

```

To decode into address, use:

```
$ printf mvm74FACaagz94rjWbNmW2EmhJdmEGcxpa | base58 -d | cut -c2- | xxd -p | head -c40
a73706385fffbf18855f2aee2a6168f29dbb597e

```


---

### Answer by username_3 on 2022-02-23. Score: 0

### Python 3

Install base58 (`pip3 install base58`) and use the following code:

```
import base58
print(base58.b58decode_check(b'mvm74FACaagz94rjWbNmW2EmhJdmEGcxpa').hex()[2:])

```

One-liner:

```
$ echo 'import base58; print(base58.b58decode_check(b"mvm74FACaagz94rjWbNmW2EmhJdmEGcxpa").hex()[2:])' | python3
a73706385fffbf18855f2aee2a6168f29dbb597e

```

Script to convert file with list of addresses to the corresponding hashes:

```
while read addr; do python3 -c "import base58; print(base58.b58decode_check(b'$addr').hex()[2:])"; done < btc.csv > btc.hash

```


---

