code: func (b *BlockChain) checkBIP0030(node *blockNode, block *btcutil.Block, view *UtxoViewpoint) error {
  	// Fetch utxos for all of the transaction ouputs in this block.
  	// Typically, there will not be any utxos for any of the outputs.
  	fetchSet := make(map[wire.OutPoint]struct{})
  	for _, tx := range block.Transactions() {
  		prevOut := wire.OutPoint{Hash: *tx.Hash()}
  		for txOutIdx := range tx.MsgTx().TxOut {
  			prevOut.Index = uint32(txOutIdx)
  			fetchSet[prevOut] = struct{}{}
  		}
  	}
  	err := view.fetchUtxos(b.db, fetchSet)
  	if err != nil {
  		return err
  	}
  
  	// Duplicate transactions are only allowed if the previous transaction
  	// is fully spent.
  	for outpoint := range fetchSet {
  		utxo := view.LookupEntry(outpoint)
  		if utxo != nil && !utxo.IsSpent() {
  			str := fmt.Sprintf("tried to overwrite transaction %v "+
  				"at block height %d that is not fully spent",
  				outpoint.Hash, utxo.BlockHeight())
  			return ruleError(ErrOverwriteTx, str)
  		}
  	}
  
  	return nil
  }
docs: // checkBIP0030 ensures blocks do not contain duplicate transactions which
  // 'overwrite' older transactions that are not fully spent.  This prevents an
  // attack where a coinbase and all of its dependent transactions could be
  // duplicated to effectively revert the overwritten transactions to a single
  // confirmation thereby making them vulnerable to a double spend.
  //
  // For more details, see
  // https://github.com/bitcoin/bips/blob/master/bip-0030.mediawiki and
  // http://r6.ca/blog/20120206T005236Z.html.
  //
  // This function MUST be called with the chain state lock held (for reads).