6

I am building a small script to decode the raw coinbase transaction data into a human-readable viewer without external scripts to better my understanding around the subject.

I've noticed that there are many different types of output script types among transactions. (P2SH, P2PK (as seen in genesis block), P2PKH, etc)

One thing I have not been able to grasp is how to obtain the Base58 address in the new SegWit P2WPK and P2WSH types.

For example, Block #542748 has this coinbase transaction which my script determines to have a pay to witness public key (P2WPK) output with 97cfc76442fe717f2a3f0cc9c175f7561b661997 as the public key hash.

The full output script: 0[] PUSHDATA(20)[97cfc76442fe717f2a3f0cc9c175f7561b661997]

Traditionally, in P2PK, P2PKH and P2SH I've used the image on this thread which works quite well.

When I apply the same method as the pubkeyhash (P2PKH) with the following operations I get a totally different address:

Append version byte: 0097CFC76442FE717F2A3F0CC9C175F7561B661997

SHA-256 Round 1: f756795a3b878d16bfa9e426a47d857830bb08a02e691f0487cbeac51b510f40

SHA-256 Digest of Round 1: ea7fe8c3b7680b79ff507c7d1b40bfc29ca8269bb1033cc84010506743cce404

Append checksum 4 bytes: 0097CFC76442FE717F2A3F0CC9C175F7561B661997ea7fe8c3

Base58 Encode: 1EqhwhM5t5NxedLoSuJ6BtBvUMLhanBLxa

This is quite different than bc1qjl8uwezzlech723lpnyuza0h2cdkvxvh54v3dn which is listed on blockchain.info's website here

What's the best way to obtain the same address they have listed (starting with bc1)?

1

1 Answer 1

8

Okay so I think I've figured it out for anyone else wondering what exactly you have to do to derive an address from this type.

In the case of the already mentioned transaction, (coinbase of block 542748) we first start by looking at the full decoded output script.

0 PUSHDATA(20) 97cfc76442fe717f2a3f0cc9c175f7561b661997

  • The very first OP_0 in the decoded script is the witness version
  • We then take the data pushed (in our case 97cfc76442fe717f2a3f0cc9c175f7561b661997) and convert it into binary
  • Then we divide the binary into 5 bit sections. In our case: 10010 11111 00111 11100 01110 11001 00010 00010 11111 11001 11000 10111 11110 01010 10001 11111 00001 10011 00100 11100 00010 11101 01111 10111 01010 11000 01101 10110 01100 00110 01100 10111
  • Then we prefix the witness version in 5 bits 00000
  • Our binary then becomes 00000 10010 11111 00111 11100 01110 11001 00010 00010 11111 11001 11000 10111 11110 01010 10001 11111 00001 10011 00100 11100 00010 11101 01111 10111 01010 11000 01101 10110 01100 00110 01100 10111
  • The first part of the address is considered the human readable portion. This is always bc on the mainnet and tb on the testnet
  • 1 is always the seperator between the human readable portion and the rest or data
  • Now our address starts with bc1 (mainnet is bc + seperator 1)
  • Now we map each 5 bits into the table here - or this alternative chart I've created
  • bc1 qjl8uwezzlech723lpnyuza0h2cdkvxvh
  • The remaining 6 characters is a checksum
  • Using the provided python code here we can compute the checksum using the bech32_create_checksum function
  • The first argument is the human readable portion as a STRING without the seperator (1)
  • The second argument is an array of integers converted from our binary data portion

Our example:

bech32_create_checksum("bc", [0, 18, 31, 7, 28, 14, 25, 2, 2, 31, 25, 24, 23, 30, 10, 17, 31, 1, 19, 4, 28, 2, 29, 15, 23, 10, 24, 13, 22, 12, 6, 12, 23] )

This gives us:

[20, 21, 12, 17, 13, 19]

Which can be mapped with our table to 54v3dn

Finally, we concatenate the human readable, seperator, decoded data, and the checksum for our final address: bc1qjl8uwezzlech723lpnyuza0h2cdkvxvh54v3dn

1
  • 1
    Good job answering your own question. You can cross reference with code for this available at github.com/sipa/bech32 Commented Sep 24, 2018 at 20:02

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.