func (view *UtxoViewpoint) AddTxOuts(tx *cashutil.Tx, blockHeight int32) {
	isCoinBase := IsCoinBase(tx)
	prevOut := wire.OutPoint{Hash: *tx.Hash()}
	for txOutIdx, txOut := range tx.MsgTx().TxOut {
		prevOut.Index = uint32(txOutIdx)
		view.addTxOut(prevOut, txOut, isCoinBase, blockHeight)
	}
}
AddTxOuts adds all outputs in the passed transaction which are not provably
unspendable to the view.  When the view already has entries for any of the
outputs, they are simply marked unspent.  All fields will be updated for
existing entries since it's possible it has changed during a reorg.
package blockchain
import (
	"fmt"
	"github.com/bcext/cashutil"
	"github.com/bcext/gcash/chaincfg/chainhash"
	"github.com/bcext/gcash/database"
	"github.com/bcext/gcash/txscript"
	"github.com/bcext/gcash/wire"
)
type txoFlags uint8
const (
	tfCoinBase txoFlags = 1 << iota
	tfSpent
	tfModified
)
type UtxoEntry struct {
	amount      int64
	pkScript    []byte  
	blockHeight int32   
	packedFlags txoFlags
}
func (entry *UtxoEntry) isModified() bool {
	return entry.packedFlags&tfModified == tfModified
}
func (entry *UtxoEntry) IsCoinBase() bool {
	return entry.packedFlags&tfCoinBase == tfCoinBase
}
func (entry *UtxoEntry) BlockHeight() int32 {
	return entry.blockHeight
}
func (entry *UtxoEntry) IsSpent() bool {
	return entry.packedFlags&tfSpent == tfSpent
}
func (entry *UtxoEntry) Spend() {
	if entry.IsSpent() {
		return
	}
	entry.packedFlags |= tfSpent | tfModified
}
func (entry *UtxoEntry) Amount() int64 {
	return entry.amount
}
func (entry *UtxoEntry) PkScript() []byte {
	return entry.pkScript
}
func (entry *UtxoEntry) Clone() *UtxoEntry {
	if entry == nil {
		return nil
	}
	return &UtxoEntry{
		amount:      entry.amount,
		pkScript:    entry.pkScript,
		blockHeight: entry.blockHeight,
		packedFlags: entry.packedFlags,
	}
}
type UtxoViewpoint struct {
	entries  map[wire.OutPoint]*UtxoEntry
	bestHash chainhash.Hash
}
func (view *UtxoViewpoint) BestHash() *chainhash.Hash {
	return &view.bestHash
}
func (view *UtxoViewpoint) SetBestHash(hash *chainhash.Hash) {
	view.bestHash = *hash
}
func (view *UtxoViewpoint) LookupEntry(outpoint wire.OutPoint) *UtxoEntry {
	return view.entries[outpoint]
}
func (view *UtxoViewpoint) addTxOut(outpoint wire.OutPoint, txOut *wire.TxOut, isCoinBase bool, blockHeight int32) {
	if txscript.IsUnspendable(txOut.PkScript) {
		return
	}
	entry := view.LookupEntry(outpoint)
	if entry == nil {
		entry = new(UtxoEntry)
		view.entries[outpoint] = entry
	}
	entry.amount = txOut.Value
	entry.pkScript = txOut.PkScript
	entry.blockHeight = blockHeight
	entry.packedFlags = tfModified
	if isCoinBase {
		entry.packedFlags |= tfCoinBase
	}
}
func (view *UtxoViewpoint) AddTxOut(tx *cashutil.Tx, txOutIdx uint32, blockHeight int32) {
	if txOutIdx >= uint32(len(tx.MsgTx().TxOut)) {
		return
	}
	prevOut := wire.OutPoint{Hash: *tx.Hash(), Index: txOutIdx}
	txOut := tx.MsgTx().TxOut[txOutIdx]
	view.addTxOut(prevOut, txOut, IsCoinBase(tx), blockHeight)
}