From 01b9dd2eabd2ce5a9bb371b0f35a4d606353c756 Mon Sep 17 00:00:00 2001 From: Ivan Kuznetsov Date: Sun, 17 Sep 2017 10:04:28 +0700 Subject: [PATCH] Implement Blockchain.FindAllUTXO --- blockchain.go | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/blockchain.go b/blockchain.go index 543ddc2..bd2e721 100644 --- a/blockchain.go +++ b/blockchain.go @@ -203,6 +203,50 @@ func (bc *Blockchain) FindUTXO(pubKeyHash []byte) []TXOutput { return UTXOs } +// FindAllUTXO finds all unspent transaction outputs and returns transactions with spent outputs removed +func (bc *Blockchain) FindAllUTXO() map[string]TXOutputs { + UTXO := make(map[string]TXOutputs) + spentTXOs := make(map[string][]int) + bci := bc.Iterator() + + for { + block := bci.Next() + + for _, tx := range block.Transactions { + txID := hex.EncodeToString(tx.ID) + + Outputs: + for outIdx, out := range tx.Vout { + // Was the output spent? + if spentTXOs[txID] != nil { + for _, spentOutIdx := range spentTXOs[txID] { + if spentOutIdx == outIdx { + continue Outputs + } + } + } + + outs := UTXO[txID] + outs.Outputs = append(outs.Outputs, out) + UTXO[txID] = outs + } + + if tx.IsCoinbase() == false { + for _, in := range tx.Vin { + inTxID := hex.EncodeToString(in.Txid) + spentTXOs[inTxID] = append(spentTXOs[inTxID], in.Vout) + } + } + } + + if len(block.PrevBlockHash) == 0 { + break + } + } + + return UTXO +} + // Iterator returns a BlockchainIterat func (bc *Blockchain) Iterator() *BlockchainIterator { bci := &BlockchainIterator{bc.tip, bc.db}