user36307: 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.)

user208: 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 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.

36307: <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>
 208: <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>
