fix indetation

pull/2/head
Minh Doan 7 years ago
parent 73b873b90b
commit 800cdb575d
  1. 16
      .vscode/settings.json
  2. 120
      blockchain.go
  3. 42
      transaction.go

@ -1,8 +1,10 @@
{ {
"workbench.colorTheme": "Solarized Light", "workbench.colorTheme": "Solarized Light",
"npm.enableScriptExplorer": true, "npm.enableScriptExplorer": true,
"window.zoomLevel": 3, "window.zoomLevel": 3,
"editor.tabSize": 4, "editor.tabSize": 4,
"editor.insertSpaces": true, "editor.insertSpaces": true,
"editor.detectIndentation": true "editor.detectIndentation": false,
} "editor.tabCompletion": true,
}

@ -1,98 +1,98 @@
package main package main
import ( import (
"encoding/hex" "encoding/hex"
) )
// Blockchain keeps a sequence of Blocks // Blockchain keeps a sequence of Blocks
type Blockchain struct { type Blockchain struct {
blocks []*Block blocks []*Block
} }
// AddBlock saves provided data as a block in the blockchain // AddBlock saves provided data as a block in the blockchain
func (bc *Blockchain) AddBlock(data string) { func (bc *Blockchain) AddBlock(data string) {
prevBlock := bc.blocks[len(bc.blocks)-1] prevBlock := bc.blocks[len(bc.blocks)-1]
// TODO(minhdoan): Parse data. // TODO(minhdoan): Parse data.
newBlock := NewBlock({}, prevBlock.Hash) newBlock := NewBlock({}, prevBlock.Hash)
bc.blocks = append(bc.blocks, newBlock) bc.blocks = append(bc.blocks, newBlock)
} }
// NewBlockchain creates a new Blockchain with genesis Block // NewBlockchain creates a new Blockchain with genesis Block
func NewBlockchain() *Blockchain { func NewBlockchain() *Blockchain {
return &Blockchain{[]*Block{NewGenesisBlock()}} return &Blockchain{[]*Block{NewGenesisBlock()}}
} }
// FindUnspentTransactions returns a list of transactions containing unspent outputs // FindUnspentTransactions returns a list of transactions containing unspent outputs
func (bc *Blockchain) FindUnspentTransactions(address string) []Transaction { func (bc *Blockchain) FindUnspentTransactions(address string) []Transaction {
var unspentTXs []Transaction var unspentTXs []Transaction
spentTXOs := make(map[string][]int) spentTXOs := make(map[string][]int)
for index := len(bc.blocks) - 1; index >= 0; index-- { for index := len(bc.blocks) - 1; index >= 0; index-- {
block := bc.blocks[index]; block := bc.blocks[index];
BreakTransaction: BreakTransaction:
for _, tx := range block.Transactions { for _, tx := range block.Transactions {
txId := hex.EncodeToString(tx.Id) txId := hex.EncodeToString(tx.Id)
idx := -1 idx := -1
if spentTXOs[txId] != nil { if spentTXOs[txId] != nil {
idx = 0 idx = 0
} }
for outIdx, txOutput := range tx.txOutput { for outIdx, txOutput := range tx.txOutput {
if idx >= 0 && spentTXOs[txId][idx] == outIdx { if idx >= 0 && spentTXOs[txId][idx] == outIdx {
idx++ idx++
continue 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 // FindUTXO finds and returns all unspent transaction outputs
func (bc *Blockchain) FindUTXO(address string) []TXOutput { func (bc *Blockchain) FindUTXO(address string) []TXOutput {
var UTXOs []TXOutput var UTXOs []TXOutput
unspentTXs := bc.FindUnspentTransactions(address) unspentTXs := bc.FindUnspentTransactions(address)
for _, tx := range unspentTXs { for _, tx := range unspentTXs {
for _, txOutput := range tx.txOutput { for _, txOutput := range tx.txOutput {
if txOutput.address == address { if txOutput.address == address {
UTXOs = append(UTXOs, txOutput) UTXOs = append(UTXOs, txOutput)
break break
} }
}
} }
}
return UTXOs return UTXOs
} }
// FindSpendableOutputs finds and returns unspent outputs to reference in inputs // FindSpendableOutputs finds and returns unspent outputs to reference in inputs
func (bc *Blockchain) FindSpendableOutputs(address string, amount int) (int, map[string][]int) { func (bc *Blockchain) FindSpendableOutputs(address string, amount int) (int, map[string][]int) {
unspentOutputs := make(map[string][]int) unspentOutputs := make(map[string][]int)
unspentTXs := bc.FindUnspentTransactions(address) unspentTXs := bc.FindUnspentTransactions(address)
accumulated := 0 accumulated := 0
Work: Work:
for _, tx := range unspentTXs { for _, tx := range unspentTXs {
txID := hex.EncodeToString(tx.ID) txID := hex.EncodeToString(tx.ID)
for outIdx, txOutput := range tx.txOutput { for outIdx, txOutput := range tx.txOutput {
if txOutput.address == address && accumulated < amount { if txOutput.address == address && accumulated < amount {
accumulated += txOutput.value accumulated += txOutput.value
unspentOutputs[txID] = append(unspentOutputs[txID], outIdx) unspentOutputs[txID] = append(unspentOutputs[txID], outIdx)
if accumulated >= amount { if accumulated >= amount {
break Work break Work
}
}
} }
}
} }
}
return accumulated, unspentOutputs return accumulated, unspentOutputs
} }

@ -1,40 +1,40 @@
package main package main
import ( import (
"bytes" "bytes"
"crypto/sha256" "crypto/sha256"
"encoding/gob" "encoding/gob"
"log" "log"
) )
// Transaction represents a Bitcoin transaction // Transaction represents a Bitcoin transaction
type Transaction struct { type Transaction struct {
id []byte id []byte
txInput []TXInput txInput []TXInput
txOutput []TXOutput txOutput []TXOutput
} }
type TXOutput struct { type TXOutput struct {
address string address string
value int value int
} }
type TXInput struct { type TXInput struct {
txId []byte txId []byte
txOutputIndex int txOutputIndex int
address string address string
} }
// SetID sets ID of a transaction // SetID sets ID of a transaction
func (tx *Transaction) SetId() { func (tx *Transaction) SetId() {
var encoded bytes.Buffer var encoded bytes.Buffer
var hash [32]byte var hash [32]byte
enc := gob.NewEncoder(&encoded) enc := gob.NewEncoder(&encoded)
err := enc.Encode(tx) err := enc.Encode(tx)
if err != nil { if err != nil {
log.Panic(err) log.Panic(err)
} }
hash = sha256.Sum256(encoded.Bytes()) hash = sha256.Sum256(encoded.Bytes())
tx.ID = hash[:] tx.ID = hash[:]
} }

Loading…
Cancel
Save