<p>There should be no endianness issues here at all.</p>
<p>Bitcoin's handing of endianness is sometimes weird in its human interfaces (e.g. transaction and block hashes are printed in reverse order, because Bitcoin interprets them as little-endian numbers, which then get printed for human consumption in big-endian order). No such issues exist at the binary protocol level, or inside the script interpreter, though.</p>
<p>I compute the Hash160 of the public key you posted correctly, with this Python code (it needs the <a href="https://github.com/bitcoin/bitcoin/blob/v23.0/test/functional/test_framework/ripemd160.py" rel="nofollow noreferrer">ripemd160</a> module, since recent version of Python do not ship with it built-in anymore):</p>
<pre><code>import hashlib
import ripemd160

pubkey = bytes.fromhex(&quot;03a6a9b25d8cd811af3162222d5e6ddaf876f915ae37ccb4b4b3f2ba56c39e26d2&quot;)
pkhash = ripemd160.ripemd160(hashlib.sha256(pubkey).digest())
print(&quot;%s&quot; % pkhash.hex())
</code></pre>
<p>Output:</p>
<pre><code>$ python3 testhash.py 
55391f93c7409df890be2804aa3cf85b22a903c1
</code></pre>
<p>I obviously can't tell you what you're doing wrong without seeing the actual code you're using, but it must not be exactly the same as what this code does.</p>

CC BY-SA 4.0
2022-06-12T14:30:17.550Z
Found it elsewhere in my script thanks for the confirmation I was doing something wrong (seriously, that's what I needed to know!)
davidbak
CC BY-SA 4.0
2022-06-10T15:07:55.167Z
Thanks Peter, i will look again.
davidbak
CC BY-SA 4.0
2022-06-10T13:43:03.650Z
2022-06-10T13:43:03.650Z
Pieter Wuille
<p>Given an address as follows:</p>
<pre><code>&gt; spend_address=$(btc-cli getnewaddress '' legacy)
&gt; btc-cli getaddressinfo $spend_address

spend_address info {
  &quot;address&quot;: &quot;moHaAMoTLRZ7dCyP4SunTBRvSfdFxUNrCe&quot;,
  &quot;scriptPubKey&quot;: &quot;76a91455391f93c7409df890be2804aa3cf85b22a903c188ac&quot;,
  &quot;isscript&quot;: false,
  &quot;iswitness&quot;: false,
  &quot;pubkey&quot;: &quot;03a6a9b25d8cd811af3162222d5e6ddaf876f915ae37ccb4b4b3f2ba56c39e26d2&quot;,
  &quot;iscompressed&quot;: true,
  ...&lt;stuff not needed for example elided&gt;...
}
</code></pre>
<p>So we have <code>pubkey</code> = <code>03a6a9b25d8cd811af3162222d5e6ddaf876f915ae37ccb4b4b3f2ba56c39e26d2</code>.</p>
<p>And if we decode the <code>ScriptPubKey</code> we find the <code>HASH160</code> embedded in it: <code>55391f93c7409df890be2804aa3cf85b22a903c1</code></p>
<p>Problem is I can't get from <code>pubkey</code> to <code>HASH160(pubkey)</code>.  Somewhere I'm baffled by endianness. (I determined that by looking at intermediate results in the wallet's <code>getaddressinfo</code> handler.)</p>
<p>I've tried:</p>
<pre><code>(ripemd160 (sha256 spend_address_pubkey))
(ripemd160 (sha256 (reversebytes spend_address_pubkey)))
(ripemd160 (reversebytes (sha256 spend_address_pubkey)))
(reversebytes (ripemd160 (sha256 spend_address_pubkey)))
(ripemd160 (reversebytes (sha256 (reversebytes spend_address_pubkey))))
</code></pre>
<p>and none of those (or their byte reverses!) match the transactions <code>HASH160(pubkey)</code> in the <code>vout[0].scriptPubKey.asm</code> field. Help me find which end to work from please!</p>
<p>(I do know how to get the <code>HASH160</code> straight from the address by stripping off the checksum.  But I want to know how to get it from the pubkey, given the standard ways in which keys and hashes are displayed w.r.t. endianness.)</p>

CC BY-SA 4.0
2022-06-12T11:35:36.687Z
@Michael Folkson I had reverted your #python tag earlier because while my answer uses Python, that's not what the question is about.
Pieter Wuille
CC BY-SA 4.0
2022-06-12T11:39:22.660Z
@PieterWuille: Ok fair enough, I'll remove it. I thought it would be nice to gather Python code answers under Python tag but you're right, the tag is for the question rather than the answer.
Michael Folkson
<address><public-key><sha256><ripemd160>
Baffled by endianness: How do I compute the HASH160 of the public key of a base58 address?
davidbak
# Baffled by endianness: How do I compute the HASH160 of the public key of a base58 address?

(Asked by: username_0 on 2022-06-10)

Given an address as follows:

```
> spend_address=$(btc-cli getnewaddress '' legacy)
> btc-cli getaddressinfo $spend_address

spend_address info {
  "address": "moHaAMoTLRZ7dCyP4SunTBRvSfdFxUNrCe",
  "scriptPubKey": "76a91455391f93c7409df890be2804aa3cf85b22a903c188ac",
  "isscript": false,
  "iswitness": false,
  "pubkey": "03a6a9b25d8cd811af3162222d5e6ddaf876f915ae37ccb4b4b3f2ba56c39e26d2",
  "iscompressed": true,
  ...<stuff not needed for example elided>...
}

```

So we have `pubkey` = `03a6a9b25d8cd811af3162222d5e6ddaf876f915ae37ccb4b4b3f2ba56c39e26d2`.

And if we decode the `ScriptPubKey` we find the `HASH160` embedded in it: `55391f93c7409df890be2804aa3cf85b22a903c1`

Problem is I can't get from `pubkey` to `HASH160(pubkey)`. Somewhere I'm baffled by endianness. (I determined that by looking at intermediate results in the wallet's `getaddressinfo` handler.)

I've tried:

```
(ripemd160 (sha256 spend_address_pubkey))
(ripemd160 (sha256 (reversebytes spend_address_pubkey)))
(ripemd160 (reversebytes (sha256 spend_address_pubkey)))
(reversebytes (ripemd160 (sha256 spend_address_pubkey)))
(ripemd160 (reversebytes (sha256 (reversebytes spend_address_pubkey))))

```

and none of those (or their byte reverses!) match the transactions `HASH160(pubkey)` in the `vout[0].scriptPubKey.asm` field. Help me find which end to work from please!

(I do know how to get the `HASH160` straight from the address by stripping off the checksum. But I want to know how to get it from the pubkey, given the standard ways in which keys and hashes are displayed w.r.t. endianness.)

**Tags:** address, public-key, sha256, ripemd160

> **Comments:**
> **username_1**: @username_2 I had reverted your #python tag earlier because while my answer uses Python, that's not what the question is about.  
> **username_2**: @username_1: Ok fair enough, I'll remove it. I thought it would be nice to gather Python code answers under Python tag but you're right, the tag is for the question rather than the answer.  

---

## 1 answers

### Answer by username_1 on 2022-06-10. Score: 3 | Accepted answer

There should be no endianness issues here at all.

Bitcoin's handing of endianness is sometimes weird in its human interfaces (e.g. transaction and block hashes are printed in reverse order, because Bitcoin interprets them as little-endian numbers, which then get printed for human consumption in big-endian order). No such issues exist at the binary protocol level, or inside the script interpreter, though.

I compute the Hash160 of the public key you posted correctly, with this Python code (it needs the [ripemd160](https://github.com/bitcoin/bitcoin/blob/v23.0/test/functional/test_framework/ripemd160.py) module, since recent version of Python do not ship with it built-in anymore):

```
import hashlib
import ripemd160

pubkey = bytes.fromhex("03a6a9b25d8cd811af3162222d5e6ddaf876f915ae37ccb4b4b3f2ba56c39e26d2")
pkhash = ripemd160.ripemd160(hashlib.sha256(pubkey).digest())
print("%s" % pkhash.hex())

```

Output:

```
$ python3 testhash.py 
55391f93c7409df890be2804aa3cf85b22a903c1

```

I obviously can't tell you what you're doing wrong without seeing the actual code you're using, but it must not be exactly the same as what this code does.

> **Comments:**
> **username_0**: Thanks Peter, i will look again.  
> **username_0**: Found it elsewhere in my script thanks for the confirmation I was doing something wrong (seriously, that's what I needed to know!)  

---

