Minor improvements
This commit is contained in:
parent
6388b20f32
commit
78dbfc69b6
|
@ -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
2
cli.go
|
@ -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!")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue