<blockquote>
<p><strong>This site says that I have to use <em>flags</em> to extract out the transaction amounts [...] Also, what are the <em>end markers</em> I could use to extract that amount?</strong></p>
</blockquote>
<p>(my <em>emphasis</em>)</p>
<p>My advice is don't search the hex data for magic flag or marker values, parse the data completely:</p>
<hr />
<p>Here's how I would parse a raw transaction in network format and start to calculate the transaction value:</p>
<pre class="lang-go prettyprint-override"><code>/* Example basic parsing blockchain transaction data, Redgrittybrick 2023 */
package main

import (
    &quot;bytes&quot;
    &quot;encoding/binary&quot;
    &quot;encoding/hex&quot;
    &quot;fmt&quot;
    &quot;os&quot;
)

const txhex string = 
    &quot;0200000000010179aaafbe7c9d3b0812a489facaf77508c08c190ec7dfd82f12&quot; +
    &quot;9aeb995aca23ab0000000000fdffffff020bd2190000000000160014d2caa7b0&quot; +
    &quot;8db89cd62c9af34da53332d30e53bb1598151b00000000001600143d4427468c&quot; +
    &quot;be7ae396427a1aa9128fa05b18c7db024730440220573fd27574cfdde4843476&quot; +
    &quot;21e1f48f85ae975cb8c2265a04496ded038896822302204a5e04a3a2d160c315&quot; +
    &quot;8caa39b58bfc91ac64c484078ec0225a7d4d2d4454661f012103d96e3819b522&quot; +
    &quot;45e42c76f869c9a875f6ea5344cf1aee2e6b3ab03adcfef0d80ede3b0b00&quot;

func main() {
    txbin, err := hex.DecodeString(txhex)
    check(err)

    buf := bytes.NewBuffer(txbin)

    // VERSION
    version := buf.Next(4)
    fmt.Printf(&quot;Version = %x\n&quot;, version)

    // OPTIONAL SEGWIT MARKER AND FLAG
    // OR INPUT COUNT
    var segwitMarker, segwitFlag byte // each defaults to 0
    inputCount := NextCInt(buf)
    if inputCount == 0 { // It's a Segwit marker, not an input count
        segwitFlag, err = buf.ReadByte() // expect 1
        check(err)
        fmt.Printf(&quot;Segwit Marker = %x, Flag = %x\n&quot; segwitMarker, segwitFlag)
        inputCount = NextCInt(buf)
    }
    fmt.Printf(&quot;Input Count = %d\n&quot;, inputCount)


    // INPUTS
    for i := 0; i &lt; int(inputCount); i++ {
        txid := buf.Next(32)
        vout := binary.LittleEndian.Uint32(buf.Next(4))
        scriptLen := NextCInt(buf)
        fmt.Printf(&quot;Input %d: tx = %x vout = %d\n&quot;, i+1, txid, vout)
        fmt.Printf(&quot;\tUnlocking Script length = %d\n&quot;, scriptLen)
        if scriptLen &gt; 0 {
            script := buf.Next(int(scriptLen))
            fmt.Printf(&quot;\tScript = %x\n&quot;, script)
        }
    }

    // SEQUENCE
    sequence := buf.Next(4)
    fmt.Printf(&quot;Sequence = %x\n&quot;, sequence)

    // OUTPUTS
    outCount := NextCInt(buf)
    fmt.Printf(&quot;Output count = %d\n&quot;, outCount)
    var txValue uint64
    for o := 0; o &lt; int(outCount); o++ {
        amount := binary.LittleEndian.Uint64(buf.Next(8))
        scriptLen := NextCInt(buf)
        script := buf.Next(int(scriptLen))
        fmt.Printf(&quot;Output %d: value = %d script = %x\n&quot;, o+1, amount, script)
        txValue += amount
    }


    //WITNESSES
    if segwitFlag != 0 {
        for i:=0; i&lt;int(inputCount); i++ {
            compCount := NextCInt(buf)
            for c:=0; c&lt;int(compCount); c++ {
                l := NextCInt(buf)
                if l &gt; 0 {
                    component := buf.Next(int(l))
                    fmt.Printf(&quot;Witness %d component %d = %x\n&quot;, 
                        i+1, c+1, component)
                }
            }
        }
    }

    // LOCKTIME
    lockTime := buf.Next(4)
    fmt.Printf(&quot;Locktime  = %x\n&quot;, lockTime)

    // DERIVED DATA
    fmt.Printf(&quot;\n(Tx value (less fee) = %d)\n&quot;, txValue)
}

// Extracts a Compact Int
func NextCInt(buf *bytes.Buffer) (uint64) {
    var result uint64
    first, err := buf.ReadByte()
    check(err)
    switch first {
    case 0xFF :
        result = binary.LittleEndian.Uint64(buf.Next(8))
    case 0xFE :
        result = uint64(binary.LittleEndian.Uint32(buf.Next(4)))
    case 0xFD :
        result = uint64(binary.LittleEndian.Uint16(buf.Next(2)))
    default :
        result = uint64(first)
    }
    return result
}

// Rudimentary error handling
func check(err error) {
    if err != nil {
        fmt.Fprint(os.Stderr, err)
        os.Exit(1)
    }
}
</code></pre>
<p>Output</p>
<pre><code>Version = 02000000
Segwit Marker = 0, Flag = 1
Input Count = 1
Input 1: tx = 79aaafbe7c9d3b0812a489facaf77508c08c190ec7dfd82f129aeb995aca23ab vout = 0
        Unlocking Script length = 0
Sequence = fdffffff
Output count = 2
Output 1: value = 1692171 script = 0014d2caa7b08db89cd62c9af34da53332d30e53bb15
Output 2: value = 1775000 script = 00143d4427468cbe7ae396427a1aa9128fa05b18c7db
Witness 1 component 1 = 30440220573fd27574cfdde484347621e1f48f85ae975cb8c2265a04496ded038896822302204a5e04a3a2d160c3158caa39b58bfc91ac64c484078ec0225a7d4d2d4454661f01
Witness 1 component 2 = 03d96e3819b52245e42c76f869c9a875f6ea5344cf1aee2e6b3ab03adcfef0d80e
Locktime  = de3b0b00

(Tx value (less fee) = 3467171)
</code></pre>
<p>The code is quick and dirty. Production code needs more defensive error checking in case of corrupt, invalid or truncated data. For example it should use <code>buf.Read()</code> instead of <code>buf.Next()</code> and check for errors thrown. Normally I'd populate an object (go data struct) instead of just printing stuff out. To calculate the fee you need to extract vout value from referenced prior transactions, fee=sum(ins)-sum(outs).</p>
<p>Note that the code above has no external dependencies - the imports are just standard go libraries that come with the compiler. It doesn't rely on any Bitcoin library (which also means it is unproven code!)</p>
<p>The go compiler is a free download at  <a href="https://go.dev/" rel="nofollow noreferrer">https://go.dev/</a> it compiles to a single native execatable (and can cross-compile to other platform), A typical way to use the above might be</p>
<ul>
<li>install go compiler</li>
<li>create a project folder somewhere convenient</li>
<li>cd to folder</li>
<li>copy above go code into file named <code>main.go</code> (or anything.go)</li>
<li><code>go mod init</code></li>
<li><code>go mod tidy</code></li>
<li><code>go build</code></li>
<li>run new program</li>
</ul>
<p>The <code>go mod ...</code> commands are project initialisation and don't need to be repeated when recompiling.</p>
<p>It is certainly more than possible this code has other flaws (comments welcome) but I hope it acts as a potential starting point or at least suggests a possible approach that can be implemented in your preferred programming language.</p>

CC BY-SA 4.0
2023-02-28T16:59:51.997Z
2023-02-28T22:44:08.697Z
2023-02-28T22:44:08.697Z
RedGrittyBrick
<p>It's not clear what method you are using, parsing raw block data or CLI/RPC calls. Since you are only asking for values the basic principle is simple.</p>
<p>Pick a block, and use <code>getblock blockHash 2</code> but replace blockHash with actual hash. The 2 will return details on each transaction in the block as if you did a <code>getrawtransaction</code> on every transaction.</p>
<p>Now all you need to do is add up all the output values for each transaction.</p>

CC BY-SA 4.0
2023-02-28T14:04:08.263Z
2023-02-28T14:04:08.263Z
m1xolyd1an
<p>I'm parsing bitcoin transactions and would like to be able to strip out transaction amounts. <a href="https://en.bitcoin.it/wiki/Protocol_documentation" rel="nofollow noreferrer">This site</a> says that I have to use flags to extract out the transaction amounts but it appears to only take one address into account. Does the same logic hold if I were to apply other flags to the amounts I'm extracting? Also, what are the end markers I could use to extract that amount?</p>
<p>Thank you in advance.</p>

CC BY-SA 4.0
2023-02-28T00:50:11.010Z
I suggest you study some existing code that does transaction parsing, which exists for almost any programming language you'd want. Even if you can't use it directly, it'll teach you more than asking dozens of questions here for every misunderstanding you have.
Pieter Wuille
CC BY-SA 4.0
2023-02-28T00:52:29.590Z
I don't understand your question; what flags are you talking about? The ones in the transaction format to indicate the BIP144 witness serialization? You need to those know whether witnesses are present, but they're unrelated to amounts. Amounts are just 8 byte values, always, without any end markers. I also don't see anything on that page that assumes there is just one address (and even further: addresses don't exist at the protocol level, only scripts/inputs/outputs).
Pieter Wuille
<transactions>
How to extract transaction amounts from tx block?
bitcoinluvr6969
# How to extract transaction amounts from tx block?

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

I'm parsing bitcoin transactions and would like to be able to strip out transaction amounts. [This site](https://en.bitcoin.it/wiki/Protocol_documentation) says that I have to use flags to extract out the transaction amounts but it appears to only take one address into account. Does the same logic hold if I were to apply other flags to the amounts I'm extracting? Also, what are the end markers I could use to extract that amount?

Thank you in advance.

**Tags:** transactions

> **Comments:**
> **username_1**: I suggest you study some existing code that does transaction parsing, which exists for almost any programming language you'd want. Even if you can't use it directly, it'll teach you more than asking dozens of questions here for every misunderstanding you have.  
> **username_1**: I don't understand your question; what flags are you talking about? The ones in the transaction format to indicate the BIP144 witness serialization? You need to those know whether witnesses are present, but they're unrelated to amounts. Amounts are just 8 byte values, always, without any end markers. I also don't see anything on that page that assumes there is just one address (and even further: addresses don't exist at the protocol level, only scripts/inputs/outputs).  

---

## 2 answers

### Answer by username_2 on 2023-02-28. Score: 3 | Accepted answer

> **This site says that I have to use *flags* to extract out the transaction amounts [...] Also, what are the *end markers* I could use to extract that amount?**

(my *emphasis*)

My advice is don't search the hex data for magic flag or marker values, parse the data completely:

---

Here's how I would parse a raw transaction in network format and start to calculate the transaction value:

```go
/* Example basic parsing blockchain transaction data, username_2 2023 */
package main

import (
    "bytes"
    "encoding/binary"
    "encoding/hex"
    "fmt"
    "os"
)

const txhex string = 
    "0200000000010179aaafbe7c9d3b0812a489facaf77508c08c190ec7dfd82f12" +
    "9aeb995aca23ab0000000000fdffffff020bd2190000000000160014d2caa7b0" +
    "8db89cd62c9af34da53332d30e53bb1598151b00000000001600143d4427468c" +
    "be7ae396427a1aa9128fa05b18c7db024730440220573fd27574cfdde4843476" +
    "21e1f48f85ae975cb8c2265a04496ded038896822302204a5e04a3a2d160c315" +
    "8caa39b58bfc91ac64c484078ec0225a7d4d2d4454661f012103d96e3819b522" +
    "45e42c76f869c9a875f6ea5344cf1aee2e6b3ab03adcfef0d80ede3b0b00"

func main() {
    txbin, err := hex.DecodeString(txhex)
    check(err)

    buf := bytes.NewBuffer(txbin)

    // VERSION
    version := buf.Next(4)
    fmt.Printf("Version = %x\n", version)

    // OPTIONAL SEGWIT MARKER AND FLAG
    // OR INPUT COUNT
    var segwitMarker, segwitFlag byte // each defaults to 0
    inputCount := NextCInt(buf)
    if inputCount == 0 { // It's a Segwit marker, not an input count
        segwitFlag, err = buf.ReadByte() // expect 1
        check(err)
        fmt.Printf("Segwit Marker = %x, Flag = %x\n" segwitMarker, segwitFlag)
        inputCount = NextCInt(buf)
    }
    fmt.Printf("Input Count = %d\n", inputCount)

    // INPUTS
    for i := 0; i < int(inputCount); i++ {
        txid := buf.Next(32)
        vout := binary.LittleEndian.Uint32(buf.Next(4))
        scriptLen := NextCInt(buf)
        fmt.Printf("Input %d: tx = %x vout = %d\n", i+1, txid, vout)
        fmt.Printf("\tUnlocking Script length = %d\n", scriptLen)
        if scriptLen > 0 {
            script := buf.Next(int(scriptLen))
            fmt.Printf("\tScript = %x\n", script)
        }
    }

    // SEQUENCE
    sequence := buf.Next(4)
    fmt.Printf("Sequence = %x\n", sequence)

    // OUTPUTS
    outCount := NextCInt(buf)
    fmt.Printf("Output count = %d\n", outCount)
    var txValue uint64
    for o := 0; o < int(outCount); o++ {
        amount := binary.LittleEndian.Uint64(buf.Next(8))
        scriptLen := NextCInt(buf)
        script := buf.Next(int(scriptLen))
        fmt.Printf("Output %d: value = %d script = %x\n", o+1, amount, script)
        txValue += amount
    }

    //WITNESSES
    if segwitFlag != 0 {
        for i:=0; i<int(inputCount); i++ {
            compCount := NextCInt(buf)
            for c:=0; c<int(compCount); c++ {
                l := NextCInt(buf)
                if l > 0 {
                    component := buf.Next(int(l))
                    fmt.Printf("Witness %d component %d = %x\n", 
                        i+1, c+1, component)
                }
            }
        }
    }

    // LOCKTIME
    lockTime := buf.Next(4)
    fmt.Printf("Locktime  = %x\n", lockTime)

    // DERIVED DATA
    fmt.Printf("\n(Tx value (less fee) = %d)\n", txValue)
}

// Extracts a Compact Int
func NextCInt(buf *bytes.Buffer) (uint64) {
    var result uint64
    first, err := buf.ReadByte()
    check(err)
    switch first {
    case 0xFF :
        result = binary.LittleEndian.Uint64(buf.Next(8))
    case 0xFE :
        result = uint64(binary.LittleEndian.Uint32(buf.Next(4)))
    case 0xFD :
        result = uint64(binary.LittleEndian.Uint16(buf.Next(2)))
    default :
        result = uint64(first)
    }
    return result
}

// Rudimentary error handling
func check(err error) {
    if err != nil {
        fmt.Fprint(os.Stderr, err)
        os.Exit(1)
    }
}

```

Output

```
Version = 02000000
Segwit Marker = 0, Flag = 1
Input Count = 1
Input 1: tx = 79aaafbe7c9d3b0812a489facaf77508c08c190ec7dfd82f129aeb995aca23ab vout = 0
        Unlocking Script length = 0
Sequence = fdffffff
Output count = 2
Output 1: value = 1692171 script = 0014d2caa7b08db89cd62c9af34da53332d30e53bb15
Output 2: value = 1775000 script = 00143d4427468cbe7ae396427a1aa9128fa05b18c7db
Witness 1 component 1 = 30440220573fd27574cfdde484347621e1f48f85ae975cb8c2265a04496ded038896822302204a5e04a3a2d160c3158caa39b58bfc91ac64c484078ec0225a7d4d2d4454661f01
Witness 1 component 2 = 03d96e3819b52245e42c76f869c9a875f6ea5344cf1aee2e6b3ab03adcfef0d80e
Locktime  = de3b0b00

(Tx value (less fee) = 3467171)

```

The code is quick and dirty. Production code needs more defensive error checking in case of corrupt, invalid or truncated data. For example it should use `buf.Read()` instead of `buf.Next()` and check for errors thrown. Normally I'd populate an object (go data struct) instead of just printing stuff out. To calculate the fee you need to extract vout value from referenced prior transactions, fee=sum(ins)-sum(outs).

Note that the code above has no external dependencies - the imports are just standard go libraries that come with the compiler. It doesn't rely on any Bitcoin library (which also means it is unproven code!)

The go compiler is a free download at <https://go.dev/> it compiles to a single native execatable (and can cross-compile to other platform), A typical way to use the above might be

* install go compiler
* create a project folder somewhere convenient
* cd to folder
* copy above go code into file named `main.go` (or anything.go)
* `go mod init`
* `go mod tidy`
* `go build`
* run new program

The `go mod ...` commands are project initialisation and don't need to be repeated when recompiling.

It is certainly more than possible this code has other flaws (comments welcome) but I hope it acts as a potential starting point or at least suggests a possible approach that can be implemented in your preferred programming language.


---

### Answer by username_3 on 2023-02-28. Score: 1

It's not clear what method you are using, parsing raw block data or CLI/RPC calls. Since you are only asking for values the basic principle is simple.

Pick a block, and use `getblock blockHash 2` but replace blockHash with actual hash. The 2 will return details on each transaction in the block as if you did a `getrawtransaction` on every transaction.

Now all you need to do is add up all the output values for each transaction.


---

