Skip to content

Commit

Permalink
network but not P2P
Browse files Browse the repository at this point in the history
  • Loading branch information
sasaxie committed Nov 21, 2017
1 parent 63c7355 commit d7cb66f
Show file tree
Hide file tree
Showing 17 changed files with 732 additions and 66 deletions.
16 changes: 15 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# go-blockchain

First, set **NODE_ID** to 3000 (**export NODE_ID=3000**) in the first terminal window. I’ll use badges like **NODE 3000** or **NODE 3001** before next paragraphs, for you to know what node to perform actions on.

**创建钱包**

```
Expand Down Expand Up @@ -35,12 +37,24 @@
**转账:**

```
> ./go-blockchain send -from 1321QKXdSdYXLPZiGxC9NS6HjTuDEFR119 -to 1546AtPEFt5uGyvhbRDLUoqLTy5zfUZhsY -amount 1
> ./go-blockchain send -from 1321QKXdSdYXLPZiGxC9NS6HjTuDEFR119 -to 1546AtPEFt5uGyvhbRDLUoqLTy5zfUZhsY -amount 1 -mine
> 00000013eda8154a87b0ee7ad5bf54f63cd6a0a2de89ce4bbc9f08313cf2c62a
>
> Success!
```

**启动节点**

```
> ./go-blockchain startnode
```

**设置挖矿节点**

```
> ./go-blockchain startnode -miner 14kiRgXmK5tDq3MzoM33Tz3wLZSTbBK9TK
```

**打印区块链:**

```
Expand Down
45 changes: 35 additions & 10 deletions cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"flag"
"fmt"
"log"

"os"
)

Expand All @@ -18,7 +19,8 @@ func (cli *CLI) printUsage() {
fmt.Println(" listaddresses - Lists all addresses from the wallet file")
fmt.Println(" printchain - Print all the blocks of the blockchain")
fmt.Println(" reindexutxo - Rebuilds the UTXO set")
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 -mine - Send AMOUNT of coins from FROM address to TO. Mine on the same node, when -mine is set.")
fmt.Println(" startnode -miner ADDRESS - Start a node with ID specified in NODE_ID env. var. -miner enables mining")
}

func (cli *CLI) validateArgs() {
Expand All @@ -32,19 +34,28 @@ func (cli *CLI) validateArgs() {
func (cli *CLI) Run() {
cli.validateArgs()

nodeID := os.Getenv("NODE_ID")
if nodeID == "" {
fmt.Printf("NODE_ID env. var is not set!")
os.Exit(1)
}

getBalanceCmd := flag.NewFlagSet("getbalance", flag.ExitOnError)
createBlockchainCmd := flag.NewFlagSet("createblockchain", flag.ExitOnError)
createWalletCmd := flag.NewFlagSet("createwallet", flag.ExitOnError)
listAddressesCmd := flag.NewFlagSet("listaddresses", flag.ExitOnError)
printChainCmd := flag.NewFlagSet("printchain", flag.ExitOnError)
reindexUTXOCmd := flag.NewFlagSet("reindexutxo", flag.ExitOnError)
sendCmd := flag.NewFlagSet("send", flag.ExitOnError)
startNodeCmd := flag.NewFlagSet("startnode", flag.ExitOnError)

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")
sendTo := sendCmd.String("to", "", "Destination wallet address")
sendAmount := sendCmd.Int("amount", 0, "Amount to send")
sendMine := sendCmd.Bool("mine", false, "Mine immediately on the same node")
startNodeMiner := startNodeCmd.String("miner", "", "Enable mining mode and send reward to ADDRESS")

switch os.Args[1] {
case "getbalance":
Expand Down Expand Up @@ -72,13 +83,18 @@ func (cli *CLI) Run() {
if err != nil {
log.Panic(err)
}
case "reindexutxo":
err := reindexUTXOCmd.Parse(os.Args[2:])
if err != nil {
log.Panic(err)
}
case "send":
err := sendCmd.Parse(os.Args[2:])
if err != nil {
log.Panic(err)
}
case "reindexutxo":
err := reindexUTXOCmd.Parse(os.Args[2:])
case "startnode":
err := startNodeCmd.Parse(os.Args[2:])
if err != nil {
log.Panic(err)
}
Expand All @@ -92,31 +108,31 @@ func (cli *CLI) Run() {
getBalanceCmd.Usage()
os.Exit(1)
}
cli.getBalance(*getBalanceAddress)
cli.getBalance(*getBalanceAddress, nodeID)
}

if createBlockchainCmd.Parsed() {
if *createBlockchainAddress == "" {
createBlockchainCmd.Usage()
os.Exit(1)
}
cli.createBlockchain(*createBlockchainAddress)
cli.createBlockchain(*createBlockchainAddress, nodeID)
}

if createWalletCmd.Parsed() {
cli.createWallet()
cli.createWallet(nodeID)
}

if listAddressesCmd.Parsed() {
cli.listAddresses()
cli.listAddresses(nodeID)
}

if printChainCmd.Parsed() {
cli.printChain()
cli.printChain(nodeID)
}

if reindexUTXOCmd.Parsed() {
cli.reindexUTXO()
cli.reindexUTXO(nodeID)
}

if sendCmd.Parsed() {
Expand All @@ -125,6 +141,15 @@ func (cli *CLI) Run() {
os.Exit(1)
}

cli.send(*sendFrom, *sendTo, *sendAmount)
cli.send(*sendFrom, *sendTo, *sendAmount, nodeID, *sendMine)
}

if startNodeCmd.Parsed() {
nodeID := os.Getenv("NODE_ID")
if nodeID == "" {
startNodeCmd.Usage()
os.Exit(1)
}
cli.startNode(nodeID, *startNodeMiner)
}
}
10 changes: 7 additions & 3 deletions cli/createblockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,15 @@ import (
"log"
)

func (cli *CLI) createBlockchain(address string) {
func (cli *CLI) createBlockchain(address, nodeID string) {
if !core.ValidateAddress(address) {
log.Panic("ERROR: Address is not valid")
}
bc := core.CreateBlockchain(address)
bc.DB.Close()
bc := core.CreateBlockchain(address, nodeID)
defer bc.DB.Close()

UTXOSet := core.UTXOSet{bc}
UTXOSet.Reindex()

fmt.Println("Done!")
}
6 changes: 3 additions & 3 deletions cli/createwallet.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import (
"github.com/sasaxie/go-blockchain/core"
)

func (cli *CLI) createWallet() {
wallets, _ := core.NewWallets()
func (cli *CLI) createWallet(nodeID string) {
wallets, _ := core.NewWallets(nodeID)
address := wallets.CreateWallet()
wallets.SaveToFile()
wallets.SaveToFile(nodeID)

fmt.Printf("Your new address: %s\n", address)
}
4 changes: 2 additions & 2 deletions cli/getbalance.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ import (
"log"
)

func (cli *CLI) getBalance(address string) {
func (cli *CLI) getBalance(address, nodeID string) {
if !core.ValidateAddress(address) {
log.Panic("ERROR: Address is not valid")
}
bc := core.NewBlockchain()
bc := core.NewBlockchain(nodeID)
UTXOSet := core.UTXOSet{bc}
defer bc.DB.Close()

Expand Down
4 changes: 2 additions & 2 deletions cli/listaddress.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import (
"log"
)

func (cli *CLI) listAddresses() {
wallets, err := core.NewWallets()
func (cli *CLI) listAddresses(nodeID string) {
wallets, err := core.NewWallets(nodeID)
if err != nil {
log.Panic(err)
}
Expand Down
5 changes: 3 additions & 2 deletions cli/printchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import (
"strconv"
)

func (cli *CLI) printChain() {
bc := core.NewBlockchain()
func (cli *CLI) printChain(nodeID string) {
bc := core.NewBlockchain(nodeID)
defer bc.DB.Close()

bci := bc.Iterator()
Expand All @@ -16,6 +16,7 @@ func (cli *CLI) printChain() {
block := bci.Next()

fmt.Printf("============ Block %x ============\n", block.Hash)
fmt.Printf("Height: %d\n", block.Height)
fmt.Printf("Prev. block: %x\n", block.PrevBlockHash)
pow := core.NewProofOfWork(block)
fmt.Printf("PoW: %s\n\n", strconv.FormatBool(pow.Validate()))
Expand Down
4 changes: 2 additions & 2 deletions cli/reindexutxo.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import (
"github.com/sasaxie/go-blockchain/core"
)

func (cli *CLI) reindexUTXO() {
bc := core.NewBlockchain()
func (cli *CLI) reindexUTXO(nodeID string) {
bc := core.NewBlockchain(nodeID)
UTXOSet := core.UTXOSet{bc}
UTXOSet.Reindex()

Expand Down
26 changes: 19 additions & 7 deletions cli/send.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,35 @@ import (
"log"
)

func (cli *CLI) send(from, to string, amount int) {
func (cli *CLI) send(from, to string, amount int, nodeID string, mineNow bool) {
if !core.ValidateAddress(from) {
log.Panic("ERROR: Sender address is not valid")
}
if !core.ValidateAddress(to) {
log.Panic("ERROR: Recipient address is not valid")
}

bc := core.NewBlockchain()
bc := core.NewBlockchain(nodeID)
UTXOSet := core.UTXOSet{bc}
defer bc.DB.Close()

tx := core.NewUTXOTransaction(from, to, amount, &UTXOSet)
cbTx := core.NewCoinbaseTX(from, "")
txs := []*core.Transaction{cbTx, tx}
wallets, err := core.NewWallets(nodeID)
if err != nil {
log.Panic(err)
}
wallet := wallets.GetWallet(from)

tx := core.NewUTXOTransaction(&wallet, to, amount, &UTXOSet)

if mineNow {
cbTx := core.NewCoinbaseTX(from, "")
txs := []*core.Transaction{cbTx, tx}

newBlock := bc.MineBlock(txs)
UTXOSet.Update(newBlock)
} else {
core.SendTx(core.KnownNodes[0], tx)
}

newBlock := bc.MineBlock(txs)
UTXOSet.Update(newBlock)
fmt.Println("Success!")
}
19 changes: 19 additions & 0 deletions cli/startnode.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package cli

import (
"fmt"
"github.com/sasaxie/go-blockchain/core"
"log"
)

func (cli *CLI) startNode(nodeID, minerAddress string) {
fmt.Printf("Starting node %s\n", nodeID)
if len(minerAddress) > 0 {
if core.ValidateAddress(minerAddress) {
fmt.Println("Mining is on. Address to receive rewards: ", minerAddress)
} else {
log.Panic("Wrong miner address!")
}
}
core.StartServer(nodeID, minerAddress)
}
7 changes: 4 additions & 3 deletions core/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@ type Block struct {
PrevBlockHash []byte
Hash []byte
Nonce int
Height int
}

// NewBlock creates and returns Block
func NewBlock(transactions []*Transaction, prevBlockHash []byte) *Block {
block := &Block{time.Now().Unix(), transactions, prevBlockHash, []byte{}, 0}
func NewBlock(transactions []*Transaction, prevBlockHash []byte, height int) *Block {
block := &Block{time.Now().Unix(), transactions, prevBlockHash, []byte{}, 0, height}
pow := NewProofOfWork(block)
nonce, hash := pow.Run()

Expand All @@ -30,7 +31,7 @@ func NewBlock(transactions []*Transaction, prevBlockHash []byte) *Block {

// NewGenesisBlock creates and returns genesis Block
func NewGenesisBlock(coinbase *Transaction) *Block {
return NewBlock([]*Transaction{coinbase}, []byte{})
return NewBlock([]*Transaction{coinbase}, []byte{}, 0)
}

// HashTransactions returns a hash of the transactions in the block
Expand Down
Loading

0 comments on commit d7cb66f

Please sign in to comment.