<p>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.</p>
<blockquote>
<p><strong>addresses (e.g everything between 76a914 and 88ac).</strong></p>
</blockquote>
<p>The locking script (PubKeyScript) for a P2PKH transaction output does indeed have the pattern <code>OP_DUP</code> (0x76), <code>OP_HASH160</code> (0xa9), <code>OP_PUSH20</code> (0x14), {<code>public key hash</code>}, <code>OP_EQUALVERIFY</code> (0x88), <code>OP_CHECKSIG</code> (0xac).</p>
<p>However</p>
<ol>
<li>There are many other types of locking script.</li>
<li>It is not a good choice to treat 76a914 and 88ac as magic numbers that delimit specific data in all transactions.</li>
<li>Addresses don't exist for some types of transaction output.</li>
</ol>
<blockquote>
<p><strong>&quot;amounts&quot; (e.g everything between 88ac and 19)</strong></p>
</blockquote>
<p>The byte <code>0x19</code> might occur in the amount and so can't be used as a delimiter. You should instead be extracting a <strong>fixed length</strong> 64-bit integer.</p>
<p>Also the sequence <code>0x88ac</code> might occur elsewhere, such as in the middle of a hash. Treating these values as delimiters is, in my opinion, a fatally flawed approach.</p>
<hr />
<p>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.</p>
<p>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.</p>
<p>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.</p>
<p>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.</p>
<p>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.</p>
<p>See</p>
<ul>
<li><a href="https://bitcoin.stackexchange.com/q/113631/13866">In what format does a block store the transaction data?</a></li>
<li><a href="https://bitcoin.stackexchange.com/q/113697/13866">What are the parts of a Bitcoin transaction in segwit format?</a></li>
<li><a href="https://en.bitcoin.it/wiki/Protocol_documentation#tx" rel="nofollow noreferrer">https://en.bitcoin.it/wiki/Protocol_documentation#tx</a></li>
<li><a href="https://en.bitcoin.it/wiki/Script" rel="nofollow noreferrer">https://en.bitcoin.it/wiki/Script</a></li>
</ul>

CC BY-SA 4.0
2023-02-24T10:37:38.003Z
2023-02-24T11:07:11.937Z
2023-02-24T11:07:11.937Z
RedGrittyBrick
<p>I'm researching bitcoin and noticed that when transactions come through my node I don't have an equal number of &quot;amounts&quot; (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.</p>

CC BY-SA 4.0
2023-02-23T19:01:37.727Z
Are you asking whether an address can be paid twice by the same transaction? If so, yes.
Pieter Wuille
CC BY-SA 4.0
2023-02-23T19:14:24.453Z
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
CC BY-SA 4.0
2023-02-23T19:16:53.517Z
@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?
bitcoinluvr6969
<transactions><full-node>
TX doesn't contain an equal number of transactions with bitcoin addresses
bitcoinluvr6969
# TX doesn't contain an equal number of transactions with bitcoin addresses

(Asked by: username_0 on 2023-02-23)

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.

**Tags:** transactions, full-node

> **Comments:**
> **username_1**: Are you asking whether an address can be paid twice by the same transaction? If so, yes.  
> **username_2**: 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.  
> **username_0**: @username_2, 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?  

---

## 1 answers

### Answer by username_3 on 2023-02-24. Score: 2 | Accepted answer

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).

However

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.

See

* [In what format does a block store the transaction data?](https://bitcoin.stackexchange.com/q/113631/13866)
* [What are the parts of a Bitcoin transaction in segwit format?](https://bitcoin.stackexchange.com/q/113697/13866)
* <https://en.bitcoin.it/wiki/Protocol_documentation#tx>
* <https://en.bitcoin.it/wiki/Script>


---

