Minor improvements

This commit is contained in:
Ivan Kuznetsov 2017-09-04 11:02:24 +07:00
parent 6388b20f32
commit 78dbfc69b6
4 changed files with 24 additions and 22 deletions

View File

@ -13,7 +13,7 @@ const dbFile = "blockchain.db"
const blocksBucket = "blocks" const blocksBucket = "blocks"
const genesisCoinbase = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks" const genesisCoinbase = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks"
// Blockchain keeps a sequence of Blocks // Blockchain implements interactions with a DB
type Blockchain struct { type Blockchain struct {
tip []byte tip []byte
db *bolt.DB db *bolt.DB
@ -25,8 +25,8 @@ type BlockchainIterator struct {
db *bolt.DB db *bolt.DB
} }
// AddBlock saves provided data as a block in the blockchain // MineBlock mines a new block with the provided transactions
func (bc *Blockchain) AddBlock(transactions []*Transaction) { func (bc *Blockchain) MineBlock(transactions []*Transaction) {
var lastHash []byte var lastHash []byte
err := bc.db.View(func(tx *bolt.Tx) error { err := bc.db.View(func(tx *bolt.Tx) error {
@ -60,24 +60,24 @@ func (bc *Blockchain) AddBlock(transactions []*Transaction) {
}) })
} }
// FindUnspentTransactions returns a list of transactions containing unspent outputs for an address // FindUnspentTransactions returns a list of transactions containing unspent outputs
func (bc *Blockchain) FindUnspentTransactions(address string) []*Transaction { func (bc *Blockchain) FindUnspentTransactions(address string) []*Transaction {
spentTXs := make(map[string][]int)
var unspentTXs []*Transaction var unspentTXs []*Transaction
spentTXOs := make(map[string][]int)
bci := bc.Iterator() bci := bc.Iterator()
for { for {
block := bci.Next() block := bci.Next()
for _, tx := range block.Transactions { for _, tx := range block.Transactions {
txid := hex.EncodeToString(tx.GetHash()) txID := hex.EncodeToString(tx.GetHash())
Outputs: Outputs:
for outid, out := range tx.Vout { for outIdx, out := range tx.Vout {
// Was the output spent? // Was the output spent?
if spentTXs[txid] != nil { if spentTXOs[txID] != nil {
for _, spentOut := range spentTXs[txid] { for _, spentOut := range spentTXOs[txID] {
if spentOut == outid { if spentOut == outIdx {
continue Outputs continue Outputs
} }
} }
@ -85,14 +85,15 @@ func (bc *Blockchain) FindUnspentTransactions(address string) []*Transaction {
if out.Unlock(address) { if out.Unlock(address) {
unspentTXs = append(unspentTXs, tx) unspentTXs = append(unspentTXs, tx)
continue Outputs
} }
} }
if tx.IsCoinbase() == false { if tx.IsCoinbase() == false {
for _, in := range tx.Vin { for _, in := range tx.Vin {
if in.LockedBy(address) { if in.LockedBy(address) {
inTxid := hex.EncodeToString(in.Txid) inTxID := hex.EncodeToString(in.Txid)
spentTXs[inTxid] = append(spentTXs[inTxid], in.Vout) spentTXOs[inTxID] = append(spentTXOs[inTxID], in.Vout)
} }
} }
} }
@ -119,12 +120,12 @@ func (bc *Blockchain) FindUTXOs(address string, amount int) (int, map[string][]i
Work: Work:
for _, tx := range unspentTXs { for _, tx := range unspentTXs {
txid := hex.EncodeToString(tx.GetHash()) txID := hex.EncodeToString(tx.GetHash())
for outid, out := range tx.Vout { for outIdx, out := range tx.Vout {
if out.Unlock(address) && accumulated < amount { if out.Unlock(address) && accumulated < amount {
accumulated += out.Value accumulated += out.Value
unspentOutputs[txid] = append(unspentOutputs[txid], outid) unspentOutputs[txID] = append(unspentOutputs[txID], outIdx)
if accumulated >= amount { if accumulated >= amount {
break Work break Work
@ -136,7 +137,7 @@ Work:
return accumulated, unspentOutputs return accumulated, unspentOutputs
} }
// Iterator ... // Iterator returns a BlockchainIterat
func (bc *Blockchain) Iterator() *BlockchainIterator { func (bc *Blockchain) Iterator() *BlockchainIterator {
bci := &BlockchainIterator{bc.tip, bc.db} bci := &BlockchainIterator{bc.tip, bc.db}
@ -175,7 +176,7 @@ func dbExists() bool {
// NewBlockchain creates a new Blockchain with genesis Block // NewBlockchain creates a new Blockchain with genesis Block
func NewBlockchain(address string) *Blockchain { func NewBlockchain(address string) *Blockchain {
if dbExists() == false { if dbExists() == false {
fmt.Println("No existing blockchain found. Creating one first.") fmt.Println("No existing blockchain found. Create one first.")
os.Exit(1) os.Exit(1)
} }

2
cli.go
View File

@ -78,7 +78,7 @@ func (cli *CLI) send(from, to string, amount int) {
defer bc.db.Close() defer bc.db.Close()
tx := NewUTXOTransaction(from, to, amount, bc) tx := NewUTXOTransaction(from, to, amount, bc)
bc.AddBlock([]*Transaction{tx}) bc.MineBlock([]*Transaction{tx})
fmt.Println("Success!") fmt.Println("Success!")
} }

View File

@ -12,7 +12,7 @@ var (
maxNonce = math.MaxInt64 maxNonce = math.MaxInt64
) )
const targetBits = 24 const targetBits = 16
// ProofOfWork represents a proof-of-work // ProofOfWork represents a proof-of-work
type ProofOfWork struct { type ProofOfWork struct {

View File

@ -5,6 +5,7 @@ import (
"crypto/sha256" "crypto/sha256"
"encoding/gob" "encoding/gob"
"encoding/hex" "encoding/hex"
"fmt"
"log" "log"
) )
@ -62,7 +63,7 @@ func (out *TXOutput) Unlock(unlockingData string) bool {
// NewCoinbaseTX creates a new coinbase transaction // NewCoinbaseTX creates a new coinbase transaction
func NewCoinbaseTX(to, data string) *Transaction { func NewCoinbaseTX(to, data string) *Transaction {
if data == "" { if data == "" {
data = "Coinbase" data = fmt.Sprintf("Reward to '%s'", to)
} }
txin := TXInput{[]byte{}, -1, data} txin := TXInput{[]byte{}, -1, data}
@ -86,12 +87,12 @@ func NewUTXOTransaction(from, to string, value int, bc *Blockchain) *Transaction
// Build a list of inputs // Build a list of inputs
for txid, outs := range validOutputs { for txid, outs := range validOutputs {
for _, out := range outs { for _, out := range outs {
txidbytes, err := hex.DecodeString(txid) txID, err := hex.DecodeString(txid)
if err != nil { if err != nil {
log.Panic(err) log.Panic(err)
} }
input := TXInput{txidbytes, out, from} input := TXInput{txID, out, from}
inputs = append(inputs, input) inputs = append(inputs, input)
} }
} }