This is a recurring question (see Parse the output field of getrawtransaction to generate a common address hash ), but I have a different spin.

Consider the following scriptPubKey field:

  "scriptPubKey": {
    "asm": "0400d0ade32217e076945e0946ef7bed72d9aea035aa8891e4bf0749ae6e24f8a7d3ea56efafe472ac3943dbed3af7c093729720ac9ab04e8eba09286e3a00fe41 OP_CHECKSIG",
    "hex": "410400d0ade32217e076945e0946ef7bed72d9aea035aa8891e4bf0749ae6e24f8a7d3ea56efafe472ac3943dbed3af7c093729720ac9ab04e8eba09286e3a00fe41ac",
    "type": "pubkey"

I was unable to construct Public Key based on the information provided in the wiki https://en.bitcoin.it/wiki/Technical_background_of_version_1_Bitcoin_addresses.

1- Given the following HEX, what is the number of bytes in the Public Key? How we can calculate it? 410400d0ade32217e076945e0946ef7bed72d9aea035aa8891e4bf0749ae6e24f8a7d3ea56efafe472ac3943dbed3af7c093729720ac9ab04e8eba09286e3a00fe41ac

2- How to reconstruct Public Key given the HEX above?

3- How are websites like Blockchair.com translating this HEX to the address 1JAL1WRvwbJqWWd1Ktks4Q89zCeUYSQM12?

2 Answers 2


P2PK scripts have the form PUSH <KEY> OP_CHECKSIG.

Your example:


Means push 0x41 (65) bytes. This is followed by the public key (starting with 04 incidicating it is an uncompressed public key). Finally, 0xac is OP_CHECKSIG.

So to summarise, the key is 0400d0ade32217e076945e0946ef7bed72d9aea035aa8891e4bf0749ae6e24f8a7d3ea56efafe472ac3943dbed3af7c093729720ac9ab04e8eba09286e3a00fe41

Question 3 is achieved following the exact steps on the wiki page you linked.

Common other formats of scriptPubKey are:

  • OP_DUP OP_HASH160 <push of 20-byte public key hash> OP_EQUALVERIFY OP_CHECKSIG (P2PKH)
  • OP_HASH160 <push of 20-byte script hash> OP_EQUAL (P2SH)
  • OP_0 <push of 20-byte key hash> (P2WPKH)
  • OP_0 <push of 32-byte script hash> (P2WSH)
  • OP_1 <push of 32-byte public key> (P2TR)

Only P2PKH and P2SH are encoded in the same way as the wiki (known as 'legacy addresses"). P2WPKH, P2WSH and P2TR addresses are all encoded with Bech32(m), known as native segwit addresses. The method for encoding these addresses is a bit more technically complex, but there are plenty of code snippets to do so online.

Note that a 20-byte push is 0x14 and a 32-byte push is 0x20.

  • Thank you for your answer. Let me send a new answer that contains a snippet code written in Python.
    – sci9
    Jan 4 at 6:28
  • I wound be grateful if you could provide some references for patterns that involve in other type of scripts.
    – sci9
    Jan 4 at 6:41
  • 1
    Done, added to my answer
    – meshcollider
    Jan 4 at 8:10
  • merci beaucoup.
    – sci9
    Jan 4 at 8:24

Here is a snippet code that demonstrate how one can create a Bitcoin address from scriptPubKey:

import binascii
import hashlib

import base58

script_pub_key_hex = "410400d0ade32217e076945e0946ef7bed72d9aea035aa8891e4bf0749ae6e24f8a7d3ea56efafe472ac3943dbed3af7c093729720ac9ab04e8eba09286e3a00fe41ac"

# generate public key hash from scriptPubKey hex
ripemd160 = hashlib.new('ripemd160')
pub_key_hash_with_version = b'\x00' + ripemd160.digest()

# generate base58check address from public key hash
address = base58.b58encode(
        pub_key_hash_with_version + hashlib.sha256(hashlib.sha256(pub_key_hash_with_version).digest()).digest()[:4])

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.