diff --git a/.vscode/settings.json b/.vscode/settings.json index 79f1a1cc0..e4062af53 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,8 +1,10 @@ { - "workbench.colorTheme": "Solarized Light", - "npm.enableScriptExplorer": true, - "window.zoomLevel": 3, - "editor.tabSize": 4, - "editor.insertSpaces": true, - "editor.detectIndentation": true -} + "workbench.colorTheme": "Solarized Light", + "npm.enableScriptExplorer": true, + "window.zoomLevel": 3, + "editor.tabSize": 4, + "editor.insertSpaces": true, + "editor.detectIndentation": false, + "editor.tabCompletion": true, + } + \ No newline at end of file diff --git a/blockchain.go b/blockchain.go index ca59be522..b71106c3b 100644 --- a/blockchain.go +++ b/blockchain.go @@ -1,98 +1,98 @@ package main import ( - "encoding/hex" + "encoding/hex" ) // Blockchain keeps a sequence of Blocks type Blockchain struct { - blocks []*Block + blocks []*Block } // AddBlock saves provided data as a block in the blockchain func (bc *Blockchain) AddBlock(data string) { - prevBlock := bc.blocks[len(bc.blocks)-1] + prevBlock := bc.blocks[len(bc.blocks)-1] - // TODO(minhdoan): Parse data. - newBlock := NewBlock({}, prevBlock.Hash) - bc.blocks = append(bc.blocks, newBlock) + // TODO(minhdoan): Parse data. + newBlock := NewBlock({}, prevBlock.Hash) + bc.blocks = append(bc.blocks, newBlock) } // NewBlockchain creates a new Blockchain with genesis Block func NewBlockchain() *Blockchain { - return &Blockchain{[]*Block{NewGenesisBlock()}} + return &Blockchain{[]*Block{NewGenesisBlock()}} } // FindUnspentTransactions returns a list of transactions containing unspent outputs func (bc *Blockchain) FindUnspentTransactions(address string) []Transaction { - var unspentTXs []Transaction - spentTXOs := make(map[string][]int) - - for index := len(bc.blocks) - 1; index >= 0; index-- { - block := bc.blocks[index]; - - BreakTransaction: - for _, tx := range block.Transactions { - txId := hex.EncodeToString(tx.Id) - - idx := -1 - if spentTXOs[txId] != nil { - idx = 0 - } - for outIdx, txOutput := range tx.txOutput { - if idx >= 0 && spentTXOs[txId][idx] == outIdx { - idx++ - continue + var unspentTXs []Transaction + spentTXOs := make(map[string][]int) + + for index := len(bc.blocks) - 1; index >= 0; index-- { + block := bc.blocks[index]; + + BreakTransaction: + for _, tx := range block.Transactions { + txId := hex.EncodeToString(tx.Id) + + idx := -1 + if spentTXOs[txId] != nil { + idx = 0 + } + for outIdx, txOutput := range tx.txOutput { + if idx >= 0 && spentTXOs[txId][idx] == outIdx { + idx++ + continue + } + + if txOutput.address == address { + unspentTXs = append(unspentTXs, *tx) + continue BreakTransaction + } + } } - - if txOutput.address == address { - unspentTXs = append(unspentTXs, *tx) - continue BreakTransaction - } - } } - } - return unspentTXs + return unspentTXs } // FindUTXO finds and returns all unspent transaction outputs func (bc *Blockchain) FindUTXO(address string) []TXOutput { - var UTXOs []TXOutput - unspentTXs := bc.FindUnspentTransactions(address) - - for _, tx := range unspentTXs { - for _, txOutput := range tx.txOutput { - if txOutput.address == address { - UTXOs = append(UTXOs, txOutput) - break - } + var UTXOs []TXOutput + unspentTXs := bc.FindUnspentTransactions(address) + + for _, tx := range unspentTXs { + for _, txOutput := range tx.txOutput { + if txOutput.address == address { + UTXOs = append(UTXOs, txOutput) + break + } + } } - } - return UTXOs + return UTXOs } // FindSpendableOutputs finds and returns unspent outputs to reference in inputs func (bc *Blockchain) FindSpendableOutputs(address string, amount int) (int, map[string][]int) { - unspentOutputs := make(map[string][]int) - unspentTXs := bc.FindUnspentTransactions(address) - accumulated := 0 + unspentOutputs := make(map[string][]int) + unspentTXs := bc.FindUnspentTransactions(address) + accumulated := 0 Work: - for _, tx := range unspentTXs { - txID := hex.EncodeToString(tx.ID) - - for outIdx, txOutput := range tx.txOutput { - if txOutput.address == address && accumulated < amount { - accumulated += txOutput.value - unspentOutputs[txID] = append(unspentOutputs[txID], outIdx) - - if accumulated >= amount { - break Work + for _, tx := range unspentTXs { + txID := hex.EncodeToString(tx.ID) + + for outIdx, txOutput := range tx.txOutput { + if txOutput.address == address && accumulated < amount { + accumulated += txOutput.value + unspentOutputs[txID] = append(unspentOutputs[txID], outIdx) + + if accumulated >= amount { + break Work + } + } } - } } - } - return accumulated, unspentOutputs + return accumulated, unspentOutputs } diff --git a/transaction.go b/transaction.go index bbcbe04f4..f37fdc7f4 100644 --- a/transaction.go +++ b/transaction.go @@ -1,40 +1,40 @@ package main import ( - "bytes" - "crypto/sha256" - "encoding/gob" - "log" + "bytes" + "crypto/sha256" + "encoding/gob" + "log" ) // Transaction represents a Bitcoin transaction type Transaction struct { - id []byte - txInput []TXInput - txOutput []TXOutput + id []byte + txInput []TXInput + txOutput []TXOutput } type TXOutput struct { - address string - value int + address string + value int } type TXInput struct { - txId []byte - txOutputIndex int - address string + txId []byte + txOutputIndex int + address string } // SetID sets ID of a transaction func (tx *Transaction) SetId() { - var encoded bytes.Buffer - var hash [32]byte + var encoded bytes.Buffer + var hash [32]byte - enc := gob.NewEncoder(&encoded) - err := enc.Encode(tx) - if err != nil { - log.Panic(err) - } - hash = sha256.Sum256(encoded.Bytes()) - tx.ID = hash[:] + enc := gob.NewEncoder(&encoded) + err := enc.Encode(tx) + if err != nil { + log.Panic(err) + } + hash = sha256.Sum256(encoded.Bytes()) + tx.ID = hash[:] }