Implement 'createblockchain' command
This commit is contained in:
parent
87eb17bbe5
commit
751d791399
|
@ -3,6 +3,7 @@ package main
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
"os"
|
||||||
|
|
||||||
"github.com/boltdb/bolt"
|
"github.com/boltdb/bolt"
|
||||||
)
|
)
|
||||||
|
@ -160,8 +161,21 @@ func (i *BlockchainIterator) Next() *Block {
|
||||||
return block
|
return block
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func dbExists() bool {
|
||||||
|
if _, err := os.Stat(dbFile); os.IsNotExist(err) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
// 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 {
|
||||||
|
fmt.Println("No existing blockchain found. Creating one first.")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
var tip []byte
|
var tip []byte
|
||||||
db, err := bolt.Open(dbFile, 0600, nil)
|
db, err := bolt.Open(dbFile, 0600, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -170,30 +184,52 @@ func NewBlockchain(address string) *Blockchain {
|
||||||
|
|
||||||
err = db.Update(func(tx *bolt.Tx) error {
|
err = db.Update(func(tx *bolt.Tx) error {
|
||||||
b := tx.Bucket([]byte(blocksBucket))
|
b := tx.Bucket([]byte(blocksBucket))
|
||||||
|
tip = b.Get([]byte("l"))
|
||||||
if b == nil {
|
|
||||||
fmt.Println("No existing blockchain found. Creating a new one...")
|
return nil
|
||||||
cbtx := NewCoinbaseTX(address, genesisCoinbase)
|
})
|
||||||
genesis := NewGenesisBlock(cbtx)
|
|
||||||
|
if err != nil {
|
||||||
b, err := tx.CreateBucket([]byte(blocksBucket))
|
log.Panic(err)
|
||||||
if err != nil {
|
}
|
||||||
log.Panic(err)
|
|
||||||
}
|
bc := Blockchain{tip, db}
|
||||||
|
|
||||||
err = b.Put(genesis.Hash, genesis.Serialize())
|
return &bc
|
||||||
if err != nil {
|
}
|
||||||
log.Panic(err)
|
|
||||||
}
|
// CreateBlockchain creates a new blockchain DB
|
||||||
|
func CreateBlockchain(address string) *Blockchain {
|
||||||
err = b.Put([]byte("l"), genesis.Hash)
|
if dbExists() {
|
||||||
if err != nil {
|
fmt.Println("Blockchain already exists.")
|
||||||
log.Panic(err)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
tip = genesis.Hash
|
|
||||||
} else {
|
var tip []byte
|
||||||
tip = b.Get([]byte("l"))
|
db, err := bolt.Open(dbFile, 0600, nil)
|
||||||
}
|
if err != nil {
|
||||||
|
log.Panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = db.Update(func(tx *bolt.Tx) error {
|
||||||
|
cbtx := NewCoinbaseTX(address, genesisCoinbase)
|
||||||
|
genesis := NewGenesisBlock(cbtx)
|
||||||
|
|
||||||
|
b, err := tx.CreateBucket([]byte(blocksBucket))
|
||||||
|
if err != nil {
|
||||||
|
log.Panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = b.Put(genesis.Hash, genesis.Serialize())
|
||||||
|
if err != nil {
|
||||||
|
log.Panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = b.Put([]byte("l"), genesis.Hash)
|
||||||
|
if err != nil {
|
||||||
|
log.Panic(err)
|
||||||
|
}
|
||||||
|
tip = genesis.Hash
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
42
cli.go
42
cli.go
|
@ -9,14 +9,21 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// CLI responsible for processing command line arguments
|
// CLI responsible for processing command line arguments
|
||||||
type CLI struct {
|
type CLI struct{}
|
||||||
bc *Blockchain
|
|
||||||
|
func (cli *CLI) createBlockchain(address string) {
|
||||||
|
bc := CreateBlockchain(address)
|
||||||
|
bc.db.Close()
|
||||||
|
fmt.Println("Done!")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cli *CLI) getBalance(address string) {
|
func (cli *CLI) getBalance(address string) {
|
||||||
|
bc := NewBlockchain(address)
|
||||||
|
defer bc.db.Close()
|
||||||
|
|
||||||
balance := 0
|
balance := 0
|
||||||
|
|
||||||
utxs := cli.bc.FindUnspentTransactions(address)
|
utxs := bc.FindUnspentTransactions(address)
|
||||||
|
|
||||||
for _, tx := range utxs {
|
for _, tx := range utxs {
|
||||||
for _, out := range tx.Vout {
|
for _, out := range tx.Vout {
|
||||||
|
@ -32,6 +39,7 @@ func (cli *CLI) getBalance(address string) {
|
||||||
func (cli *CLI) printUsage() {
|
func (cli *CLI) printUsage() {
|
||||||
fmt.Println("Usage:")
|
fmt.Println("Usage:")
|
||||||
fmt.Println(" getbalance -address ADDRESS - Get balance of ADDRESS")
|
fmt.Println(" getbalance -address ADDRESS - Get balance of ADDRESS")
|
||||||
|
fmt.Println(" createblockchain -address ADDRESS - Create a blockchain and send genesis block reward to ADDRESS")
|
||||||
fmt.Println(" printchain - Print all the blocks of the blockchain")
|
fmt.Println(" printchain - Print all the blocks of the blockchain")
|
||||||
fmt.Println(" send -from FROM -to TO -amount AMOUNT - Send AMOUNT of coins from FROM address to TO")
|
fmt.Println(" send -from FROM -to TO -amount AMOUNT - Send AMOUNT of coins from FROM address to TO")
|
||||||
}
|
}
|
||||||
|
@ -44,7 +52,11 @@ func (cli *CLI) validateArgs() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cli *CLI) printChain() {
|
func (cli *CLI) printChain() {
|
||||||
bci := cli.bc.Iterator()
|
// TODO: Fix this
|
||||||
|
bc := NewBlockchain("")
|
||||||
|
defer bc.db.Close()
|
||||||
|
|
||||||
|
bci := bc.Iterator()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
block := bci.Next()
|
block := bci.Next()
|
||||||
|
@ -62,8 +74,11 @@ func (cli *CLI) printChain() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cli *CLI) send(from, to string, amount int) {
|
func (cli *CLI) send(from, to string, amount int) {
|
||||||
tx := NewUTXOTransaction(from, to, amount)
|
bc := NewBlockchain(from)
|
||||||
cli.bc.AddBlock([]*Transaction{tx})
|
defer bc.db.Close()
|
||||||
|
|
||||||
|
tx := NewUTXOTransaction(from, to, amount, bc)
|
||||||
|
bc.AddBlock([]*Transaction{tx})
|
||||||
fmt.Println("Success!")
|
fmt.Println("Success!")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,10 +87,12 @@ func (cli *CLI) Run() {
|
||||||
cli.validateArgs()
|
cli.validateArgs()
|
||||||
|
|
||||||
getBalanceCmd := flag.NewFlagSet("getbalance", flag.ExitOnError)
|
getBalanceCmd := flag.NewFlagSet("getbalance", flag.ExitOnError)
|
||||||
|
createBlockchainCmd := flag.NewFlagSet("createblockchain", flag.ExitOnError)
|
||||||
sendCmd := flag.NewFlagSet("send", flag.ExitOnError)
|
sendCmd := flag.NewFlagSet("send", flag.ExitOnError)
|
||||||
printChainCmd := flag.NewFlagSet("printchain", flag.ExitOnError)
|
printChainCmd := flag.NewFlagSet("printchain", flag.ExitOnError)
|
||||||
|
|
||||||
getBalanceAddress := getBalanceCmd.String("address", "", "The address to get balance for")
|
getBalanceAddress := getBalanceCmd.String("address", "", "The address to get balance for")
|
||||||
|
createBlockchainAddress := createBlockchainCmd.String("address", "", "The address to send genesis block reward to")
|
||||||
sendFrom := sendCmd.String("from", "", "Source wallet address")
|
sendFrom := sendCmd.String("from", "", "Source wallet address")
|
||||||
sendTo := sendCmd.String("to", "", "Destination wallet address")
|
sendTo := sendCmd.String("to", "", "Destination wallet address")
|
||||||
sendAmount := sendCmd.Int("amount", 0, "Amount to send")
|
sendAmount := sendCmd.Int("amount", 0, "Amount to send")
|
||||||
|
@ -86,6 +103,11 @@ func (cli *CLI) Run() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Panic(err)
|
log.Panic(err)
|
||||||
}
|
}
|
||||||
|
case "createblockchain":
|
||||||
|
err := createBlockchainCmd.Parse(os.Args[2:])
|
||||||
|
if err != nil {
|
||||||
|
log.Panic(err)
|
||||||
|
}
|
||||||
case "printchain":
|
case "printchain":
|
||||||
err := printChainCmd.Parse(os.Args[2:])
|
err := printChainCmd.Parse(os.Args[2:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -109,6 +131,14 @@ func (cli *CLI) Run() {
|
||||||
cli.getBalance(*getBalanceAddress)
|
cli.getBalance(*getBalanceAddress)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if createBlockchainCmd.Parsed() {
|
||||||
|
if *createBlockchainAddress == "" {
|
||||||
|
createBlockchainCmd.Usage()
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
cli.createBlockchain(*createBlockchainAddress)
|
||||||
|
}
|
||||||
|
|
||||||
if printChainCmd.Parsed() {
|
if printChainCmd.Parsed() {
|
||||||
cli.printChain()
|
cli.printChain()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue