2

i am currently parsing blockchain transaction data from the raw hex blk00000.dat files downloaded by Bitcoin core. In order to validate, i compare my results with blockchain.info from time to time.

While the major part of my parsing is already correct, i came accross a problem with the conversion of the output script to the corresponding address.

Many of the addresses are already correctly parsed, as well, however there are some exceptions where the results are not the same as listed on blockchain.info. In my mind, it seems to be a problem with the transaction type. Apparently, for a transaction different from P2PKH, the output script will look differently, such that i cannot run the script through the same function that converts to the address all the time.

I think to have figured out that the public keys in P2PKH-transactions scripts begin with 76 all the time, is that enough to determine the type as P2PKH?

Furthermore, i came across some few transactions that begin with 4104 and end with ac. For those ones, I have to use a different function to convert to the address, then it works.

Lastly, i wanted to ask, what other transaction types i could come across? I need to parse every transaction script to an address 100% correctly, thus i need to cover all possible cases.

When searching on the web for pre-written code, i found many partly useful, but also false or maybe old snippets. What i am searching for is a general function that i can parse the output script (or the complete raw transaction string) to and that delivers the output addresses and values of BTC / Satoshi sent to these.

Of course, if you can recommend an overall python parser for the rawtx hex strings from the .dat-files, i would be also glad :) The main info i need for each transaction: - the hash of the corresponding block - transaction time (block time) - number of inputs and outputs - inputs [(block index (vout), txid), (...)] - outputs [(value, address), (...)] - the overall transaction hash

Thank you.

2 Answers 2

3

I think to have figured out that the public keys in P2PKH-transactions scripts begin with 76 all the time, is that enough to determine the type as P2PKH?

No. The 0x76 is the number of the first opcode, OP_DUP. A full P2PKH transaction has the template OP_DUP OP_HASH160 0x14 <pkh> OP_EQUALVERIFY OP_CHECKSIG.

Lastly, i wanted to ask, what other transaction types i could come across? I need to parse every transaction script to an address 100% correctly, thus i need to cover all possible cases.

Scripts can contain anything and there's not necessarily an address for them. Addresses represent specific data in standard transactions, of which there are only a few different types.

  • P2PKH (as above)
  • P2SH (OP_HASH160, 0x14 followed by the 20-byte hash of the redeem script and OP_EQUAL)
  • P2WPKH (witness version 0x00 followed by PKH)
  • P2WSH (witness version 0x00 followed by script hash)
  • P2MultiSig (OP_N, <pubKey1>..<pubKeyN> OP_M OP_CHECKMULTISIG where N <= 3)
  • OP_RETURN <data>

The first two, P2PKH and P2SH use base58 addresses beginning with 1 and 3 respectively on mainnet.

P2WPKH and P2WSH use bech32 addresses beginning with bc1 on mainnet. You can determine the difference based on their length. Witness versions > 0 are also standard, but have no known meaning - this is intended for future extensibility.

OP_RETURN and P2MS don't have standard addresses. Nor do any non-standard transactions which do not fit any of the above conventions. Addresses are intended for human readability and parsing, so that software can simply recognize what kind of output is used, and how to create the relevant scriptSig to spend them.

Standard transactions are only a policy in software used to determine which kinds of unconfirmed transactions can be accepted into the mempool. Transactions confirmed in blocks can ignore these standardness rules and contain arbitrary scripts, as long as they evaluate to true.

The full details for parsing the standard script types are defined in standard.cpp in Bitcoin Core.

2
  • 1
    P2SH transactions are HASH160 of the redeemScript so should be 20 bytes. Also they begin with OP_HASH160 0x14 <redeem_script> OP_EQUAL
    – Ugam Kamat
    Jan 24, 2020 at 12:15
  • 2
    There is also P2PK scripts (comp/uncomp pubkey + OP_CheckSig) which are standard and has no human readable form aka address. Jan 24, 2020 at 14:17
2

Lastly, i wanted to ask, what other transaction types i could come across? I need to parse every transaction script to an address 100% correctly, thus i need to cover all possible cases.

This is not possible, as not all transaction scripts correspond to an address.

Addresses are a human convenience feature, and only cover the following formats:

  • p2pkh
  • p2sh
  • p2wsh
  • p2wpkh

Anything else is non-standard, and cannot be encoded as an address. The most common such output you would find would be p2pk (I believe), which predates the original p2pkh address system. However, many explorers display it as a p2pkh address, even though that is incorrect.

When dealing with scripts, you would need to deal with the op codes. For example, 0x76 is OP_DUP, while 0xac is OP_CHECKSIG. Addresses translate to a specific set of op codes, and the address data is embedded in it.

For example, a p2pkh address contains a 20 byte payload in the base58 address. This corresponds to the payload to be embedded into the p2pkh script OP_DUP OP_HASH160 <20 byte Public KeyHash> OP_EQUAL OP_CHECKSIG.

Similarly, a p2sh address contains a 20 byte payload. However, since the address encoding is different, wallets know to embed it into a p2sh script of OP_HASH160 [20-byte-hash-value] OP_EQUAL.

You will only be able to convert the known script formats into an address.

Your Answer

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

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