9 UTXO优化
9.1 查找未花费输出
之前我们要查询 某个地址的余额需要遍历整个数据库,随着数据量的增大,这个工作量会很大,我们现在来尝试优化
/Users/xxx/go/src/publicChain/part63-UTXOSet/BLC/UTXO_Set.go
const utxoTableName = "utxoTableName"
type UTXOSet struct {
Blockchain *Blockchain
}
func (utxoSet *UTXOSet) ResetUTXOSet() {
err := utxoSet.Blockchain.DB.Update(func(tx *bolt.Tx) error {
b := tx.Bucket([]byte(utxoTableName))
if b != nil {
tx.DeleteBucket([]byte(utxoTableName))
b, _ := tx.CreateBucket([]byte(utxoTableName))
if b != nil {
}
}
return nil
})
if err != nil {
log.Panic(err)
}
}
/Users/xxx/go/src/publicChain/part62-UTXOSet/BLC/Transaction_TXOutputs.go
type TXOutputs struct {
TxOutputs []*TXOutput
}
/Users/xxx/go/src/publicChain/part62-UTXOSet/BLC/Blockchain.go
func (blockchain *Blockchain) FindUTXOMap() map[string]*TXOutputs {
//define an Iterator variable to attain block
blockchainIterator := blockchain.Iterator()
//store all UTXOs have been spent
spentableUTXOsMap := make(map[string][]*TXInput)
utxoMaps := make(map[string]*TXOutputs)
for {
//attain blocks
block := blockchainIterator.Next()
//range all index of Txs slice
for i := len(block.Txs) - 1; i >= 0; i-- {
//attain Txs
tx := block.Txs[i]
//judging if tx is in coinbase and put all txInput into slice
if tx.IsCoinbaseTransaction() == false {
for _, txInput := range tx.Vins {
//convert []byte to string
txHash := hex.EncodeToString(txInput.TxHash)
spentableUTXOsMap[txHash] = append(spentableUTXOsMap[txHash], txInput)
}
}
//define an instance of &TXOutputs
txOutputs := &TXOutputs{[]*TXOutput{}}
//convert []byte to string
txHash := hex.EncodeToString(tx.TxHash)
workOutLoop:
//range if a value has been spent
for index, out := range tx.Vouts {
//convert []byte to string
txHash := hex.EncodeToString(tx.TxHash)
//attain []*TXInput
txInputs :=