I'm researching bitcoin and noticed that when transactions come through my node I don't have an equal number of "amounts" (e.g everything between 88ac and 19) with addresses (e.g everything between 76a914 and 88ac). Why is this? I was expecting them to be equal, as in one amount being transacted per one receiving address.

  • 1
    Are you asking whether an address can be paid twice by the same transaction? If so, yes. Feb 23 at 19:01
  • 1
    Could you please be more specific about what you are looking at, what you were expecting to see, and how what you’re seeing diverges from your expectations? It’s not clear to me what you are asking.
    – Murch
    Feb 23 at 19:14
  • @Murch, yes I can. I am wanting to extract from pyshark transaction checksums. However, I don't know how to extract it from the data. Is the consecutive 4 bytes after the first 40? Feb 23 at 19:16

1 Answer 1


I suspect one cause of your problem is that you are not taking into account the full complexity of Bitcoin and are taking too many shortcuts in parsing the data.

addresses (e.g everything between 76a914 and 88ac).

The locking script (PubKeyScript) for a P2PKH transaction output does indeed have the pattern OP_DUP (0x76), OP_HASH160 (0xa9), OP_PUSH20 (0x14), {public key hash}, OP_EQUALVERIFY (0x88), OP_CHECKSIG (0xac).


  1. There are many other types of locking script.
  2. It is not a good choice to treat 76a914 and 88ac as magic numbers that delimit specific data in all transactions.
  3. Addresses don't exist for some types of transaction output.

"amounts" (e.g everything between 88ac and 19)

The byte 0x19 might occur in the amount and so can't be used as a delimiter. You should instead be extracting a fixed length 64-bit integer.

Also the sequence 0x88ac might occur elsewhere, such as in the middle of a hash. Treating these values as delimiters is, in my opinion, a fatally flawed approach.

The approach I take when parsing is to know what data type is expected next and read the appropriate number of bytes for that data type.

The only significant complication is the optional elements such as the SegWit Marker and Flag. I deal with that by checking if the number of inputs (a variable length CompactInt that you have to read in two parts) is zero and if so, treating it as a SegWit Marker instead, then reading the SegWit Flag and the real input-count.

When expecting a CompactInt I read one byte to determine the length then read the remaining number of bytes indicated and calculate the value appropriately.

This requires you to fully parse the data from the beginning - you cant dive into some random point in the middle of the data and start parsing from there. The data does not contain delimiters. Even when magic numbers are used - such as the one at the start of a block in the blockfiles, you cannot assume that the value won't occur in the middle of some hash data.

If you are parsing the scripts you need to implement something that has a basic understanding of opcodes so that you know how many bytes are data rather than opcode - that way you don't look for nonexistent markers.


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.