code: func (b *BlockChain) FetchUtxoView(tx *btcutil.Tx) (*UtxoViewpoint, error) {
  	// Create a set of needed outputs based on those referenced by the
  	// inputs of the passed transaction and the outputs of the transaction
  	// itself.
  	neededSet := make(map[wire.OutPoint]struct{})
  	prevOut := wire.OutPoint{Hash: *tx.Hash()}
  	for txOutIdx := range tx.MsgTx().TxOut {
  		prevOut.Index = uint32(txOutIdx)
  		neededSet[prevOut] = struct{}{}
  	}
  	if !IsCoinBase(tx) {
  		for _, txIn := range tx.MsgTx().TxIn {
  			neededSet[txIn.PreviousOutPoint] = struct{}{}
  		}
  	}
  
  	// Request the utxos from the point of view of the end of the main
  	// chain.
  	view := NewUtxoViewpoint()
  	b.chainLock.RLock()
  	err := view.fetchUtxosMain(b.db, neededSet)
  	b.chainLock.RUnlock()
  	return view, err
  }
docs: // FetchUtxoView loads unspent transaction outputs for the inputs referenced by
  // the passed transaction from the point of view of the end of the main chain.
  // It also attempts to fetch the utxos for the outputs of the transaction itself
  // so the returned view can be examined for duplicate transactions.
  //
  // This function is safe for concurrent access however the returned view is NOT.