1

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

2
  • 1
    @Michael Folkson I had reverted your #python tag earlier because while my answer uses Python, that's not what the question is about. Jun 12, 2022 at 11:35
  • @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. Jun 12, 2022 at 11:39

1 Answer 1

3

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.

2
  • Thanks Peter, i will look again.
    – davidbak
    Jun 10, 2022 at 15:07
  • 1
    Found it elsewhere in my script thanks for the confirmation I was doing something wrong (seriously, that's what I needed to know!)
    – davidbak
    Jun 12, 2022 at 14:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.