I'm working on extracting output addresses from tx messages in BITCOIN packets.

Currently, I extract address from output scripts which starts with 0x76(OP_DUP) like this :

76 a9 14 6d 1d 74 58 95 6e 80 cd b4 c3 3f 1e d5 8e 91 c4 92 1a 85 d0 88

but i don't have any idea about some output scripts which start with 0xA9(OP_HASH160).

As an example, i don't know in below example, what is the raw script, which is used to generate output address?

a9 14 16 52 33 02 f2 ee d0 e0 aa 6a 4c 1d 0a 41 39 6f c2 6f 53 6e 87

How i can extract output address from output scripts which start with -xA9?


The first example that you have shown is a P2PKH address. The 0x14 indicates how many bytes to push onto the stack. 0x14 is 20 in decimal so the script pushes the next 20 bytes on the stack which is 6d 1d 74 58 95 6e 80 cd b4 c3 3f 1e d5 8e 91 c4 92 1a 85 d0.

The second case is a Pay to Script Hash example (P2SH). The script is HASH160 Push 20 bytes <redeem_script> OP_EQUAL>. Hence your redeem script in the second case is 16523302f2eed0e0aa6a4c1d0a41396fc26f536e. You would need to then Base58Check it with prefix of 0x05, this gives you the address as 33j3G4xMEn4CtKL5iYnsr97ww67wYh8TPY.

Below is the python script that gives you the address:

import base58
from hashlib import sha256

redeem_script = '16523302f2eed0e0aa6a4c1d0a41396fc26f536e'
version = '05'
payload = version + redeem_script
checksum = sha256(sha256(bytes.fromhex(payload)).digest()).hexdigest()[:8]

pre_encoded_address = payload + checksum
address = base58.b58encode(bytes.fromhex(pre_encoded_address)).decode()
  • thanks, can you splain how you calculate "33j3G4xMEn4CtKL5iYnsr97ww67wYh8TPY" from this raw script : "16523302f2eed0e0aa6a4c1d0a41396fc26f536e" ??
    – Saeed
    May 18 '19 at 9:26
  • That's just Base58Check. You first append 0x05 to the redeem script. Then you double hash it with sha256 and then append the first 4 bytes at the end to 0x05+redeemscript. Those first 4 bytes is the checksum. Then you base58 encode it.
    – Ugam Kamat
    May 18 '19 at 9:57
  • Thank you a lot ! you mean that redeem script is "16523302f2eed0e0aa6a4c1d0a41396fc26f536e" then A1 is equal to "0516523302f2eed0e0aa6a4c1d0a41396fc26f536e" then A2 is sha256(sha256(first)) and then checksum is first 4 bytes of A2. then answer is base58encode(first+checksum) . but answer is not equal to "33j3G4xMEn4CtKL5iYnsr97ww67wYh8TPY" !
    – Saeed
    May 18 '19 at 10:22
  • 1
    @Saeed I have edited my answer with a python script that shows you how to get the address from the redeem script. I think the common mistake most people do is hashing the plain script rather than using the bytes from the hexadecimal.
    – Ugam Kamat
    May 18 '19 at 11:30
  • Thanks a lot. it is correct. but, what about the other op codes? it seems that each op code has a different method to extract an output address. how i can extract address from other types of op_code like "0x00" and "0x40" and etc?
    – Saeed
    May 19 '19 at 7:06

This seems to be a classical P2PKH script which start with op_dup flowed by op_hash160 if you look at the next byte there is the hex value 14 which is 20 in decimal and means read 20 byte of data and push it to the stack.

I have created a video in the past showing step by step how to dissect a P2PKH tx. Look: https://youtu.be/1n4g3eYX1UI

  • yes, it is correct about my frist example. but, what about my second example? which starts with 0xA9 and then 14 apperes? i assumed it line the first example and i read 20 byte of data to push it to stack, but the result output address is incorrect
    – Saeed
    May 18 '19 at 7:26
  • I think the general rule you have been missing is that if a hex value does not translate to an op code you should read that many bytes of data and push it to the stack. May 18 '19 at 8:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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