user140253: I'm parsing bitcoin transactions and would like to be able to strip out transaction amounts. This site 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.

user26873: 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.

user13866: 
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:
/* Example basic parsing blockchain transaction data, Redgrittybrick 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.

140253: <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>
 26873: <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>
 13866: <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>
