Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cli: show timestamp of the block #3

Open
wants to merge 24 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
c0accf3
cli: show timestamp of the block
RichardWeiYang Oct 11, 2017
5e43c77
merkle tree: fix the implementation and add a test case
RichardWeiYang Oct 16, 2017
cee6700
base58: fix Base58Decode on calculating the zeroBytes
RichardWeiYang Oct 16, 2017
f9935da
base58_test: add test case for Base58
RichardWeiYang Oct 16, 2017
782db48
cli: add three cli command for exploring
RichardWeiYang Oct 16, 2017
42b9dbb
version: display the addree when a new node is connected
RichardWeiYang Oct 18, 2017
8ea4bc8
Use View instead of Update in NewBlockchain()
RichardWeiYang Oct 18, 2017
29099f0
check wallet before sending
RichardWeiYang Oct 18, 2017
009fda2
display the number of tx mined
RichardWeiYang Oct 18, 2017
2974ee8
cli: print PubKeyHash in getAddress
RichardWeiYang Oct 18, 2017
5f4f2f5
cli: add command getPubKeyHash
RichardWeiYang Oct 18, 2017
36cfffc
cli: add getBlock command
RichardWeiYang Oct 19, 2017
01d18ce
add Address in TXOut
RichardWeiYang Oct 19, 2017
5c88b24
display the addresse in TXIn and optmize getAddress command
RichardWeiYang Oct 19, 2017
c410eb2
display the private key
RichardWeiYang Oct 20, 2017
9f6ac35
update gitignore
RichardWeiYang Oct 21, 2017
64cf474
fix private key display
RichardWeiYang Oct 21, 2017
04318d7
cli: generatePrivKey
RichardWeiYang Oct 21, 2017
b415f08
make it a package bc
RichardWeiYang Oct 22, 2017
c72ff7f
Change README for bc package
RichardWeiYang Oct 22, 2017
cb4ae18
export DB in blockchain
RichardWeiYang Oct 22, 2017
9b2f73b
add PrintHTML method to chain
RichardWeiYang Oct 22, 2017
56c9e3f
add GetBalance to chain
RichardWeiYang Oct 22, 2017
db3fe41
more detail explanation
RichardWeiYang Oct 31, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
*.db
*.dat
cscope.*
.*.swp
blockchain_go
6 changes: 4 additions & 2 deletions base58.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package bc
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm afraid this is against the idea of the project: it should be a standalone app, not a package. Why did you decide to make this change?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure, this is up to you. I just add it for my purpose.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, actually, I am not comfortable with the GitHub pull request.

Since what I want you to take is the fix on Decoder and merkle tree, the #2 - #4 commit.

While GitHub automatically create the pull request with all my new commits on master branch.

How could I send a pull request just with dedicated commit? or you could pick up the one you want? or I have to make a clean master branch so that you can pull?


import (
"bytes"
Expand Down Expand Up @@ -40,8 +40,10 @@ func Base58Decode(input []byte) []byte {
zeroBytes := 0

for _, b := range input {
if b == 0x00 {
if b == b58Alphabet[0] {
zeroBytes++
} else {
break
}
}

Expand Down
27 changes: 27 additions & 0 deletions base58_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package bc

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestBase58(t *testing.T) {
for i := 0; i < 100; i++ {
_, public := newKeyPair()
pubKeyHash := HashPubKey(public)

versionedPayload := append([]byte{version}, pubKeyHash...)
checksum := checksum(versionedPayload)

fullPayload := append(versionedPayload, checksum...)
address := Base58Encode(fullPayload)

assert.Equal(
t,
ValidateAddress(string(address[:])),
true,
"Address: %s is invalid", address,
)
}
}
2 changes: 1 addition & 1 deletion block.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package bc

import (
"bytes"
Expand Down
4 changes: 2 additions & 2 deletions blockchain.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package bc

import (
"bytes"
Expand Down Expand Up @@ -82,7 +82,7 @@ func NewBlockchain(nodeID string) *Blockchain {
log.Panic(err)
}

err = db.Update(func(tx *bolt.Tx) error {
err = db.View(func(tx *bolt.Tx) error {
b := tx.Bucket([]byte(blocksBucket))
tip = b.Get([]byte("l"))

Expand Down
2 changes: 1 addition & 1 deletion blockchain_iterator.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package bc

import (
"log"
Expand Down
100 changes: 99 additions & 1 deletion cli.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package bc

import (
"flag"
Expand All @@ -21,6 +21,14 @@ func (cli *CLI) printUsage() {
fmt.Println(" reindexutxo - Rebuilds the UTXO set")
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")
fmt.Println()
fmt.Println("Exploring cmds:")
fmt.Println(" generatePrivKey - generate KeyPair for exploring")
fmt.Println(" getPubKey -privKey PRIKEY - generate PubKey from privateKey")
fmt.Println(" getAddress -pubKey PUBKEY - convert pubKey to address")
fmt.Println(" getPubKeyHash -address Address - get pubKeyHash of an address")
fmt.Println(" validateAddress -addr Address - validate an address")
fmt.Println(" getBlock -hash BlockHash - get a block with BlockHash")
}

func (cli *CLI) validateArgs() {
Expand Down Expand Up @@ -48,6 +56,12 @@ func (cli *CLI) Run() {
reindexUTXOCmd := flag.NewFlagSet("reindexutxo", flag.ExitOnError)
sendCmd := flag.NewFlagSet("send", flag.ExitOnError)
startNodeCmd := flag.NewFlagSet("startnode", flag.ExitOnError)
generatePrivKeyCmd := flag.NewFlagSet("generatePrivKey", flag.ExitOnError)
getPubKeyCmd := flag.NewFlagSet("getPubKey", flag.ExitOnError)
getAddressCmd := flag.NewFlagSet("getAddress", flag.ExitOnError)
getPubKeyHashCmd := flag.NewFlagSet("getPubKeyHash", flag.ExitOnError)
validateAddrCmd := flag.NewFlagSet("validateAddress", flag.ExitOnError)
getBlockCmd := flag.NewFlagSet("getBlock", flag.ExitOnError)

getBalanceAddress := getBalanceCmd.String("address", "", "The address to get balance for")
createBlockchainAddress := createBlockchainCmd.String("address", "", "The address to send genesis block reward to")
Expand All @@ -56,6 +70,11 @@ func (cli *CLI) Run() {
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")
privateKey := getPubKeyCmd.String("privKey", "", "generate PubKey based on this")
pubKey := getAddressCmd.String("pubKey", "", "the key where address generated")
pubKeyAddress := getPubKeyHashCmd.String("address", "", "the pub address")
address := validateAddrCmd.String("addr", "", "the public address")
blockHash := getBlockCmd.String("hash", "", "the block hash")

switch os.Args[1] {
case "getbalance":
Expand Down Expand Up @@ -98,6 +117,36 @@ func (cli *CLI) Run() {
if err != nil {
log.Panic(err)
}
case "validateAddress":
err := validateAddrCmd.Parse(os.Args[2:])
if err != nil {
log.Panic(err)
}
case "generatePrivKey":
err := generatePrivKeyCmd.Parse(os.Args[2:])
if err != nil {
log.Panic(err)
}
case "getPubKey":
err := getPubKeyCmd.Parse(os.Args[2:])
if err != nil {
log.Panic(err)
}
case "getPubKeyHash":
err := getPubKeyHashCmd.Parse(os.Args[2:])
if err != nil {
log.Panic(err)
}
case "getAddress":
err := getAddressCmd.Parse(os.Args[2:])
if err != nil {
log.Panic(err)
}
case "getBlock":
err := getBlockCmd.Parse(os.Args[2:])
if err != nil {
log.Panic(err)
}
default:
cli.printUsage()
os.Exit(1)
Expand Down Expand Up @@ -152,4 +201,53 @@ func (cli *CLI) Run() {
}
cli.startNode(nodeID, *startNodeMiner)
}

if generatePrivKeyCmd.Parsed() {
cli.generatePrivKey()
}

if getPubKeyCmd.Parsed() {
if *privateKey == "" {
getPubKeyCmd.Usage()
os.Exit(1)
}
cli.getPubKey(*privateKey)
}

if getAddressCmd.Parsed() {
if *pubKey == "" {
getAddressCmd.Usage()
os.Exit(1)
}

cli.getAddress(*pubKey)
}

if getPubKeyHashCmd.Parsed() {
if *pubKeyAddress == "" {
getPubKeyHashCmd.Usage()
os.Exit(1)
}

cli.getPubKeyHash(*pubKeyAddress)
}

if validateAddrCmd.Parsed() {
if *address == "" {
validateAddrCmd.Usage()
os.Exit(1)
}

cli.validateAddr(*address)
}

if getBlockCmd.Parsed() {
if *blockHash == "" {
getBlockCmd.Usage()
os.Exit(1)
}

cli.printBlock(*blockHash, nodeID)
}

}
2 changes: 1 addition & 1 deletion cli_createblockchain.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package bc

import (
"fmt"
Expand Down
2 changes: 1 addition & 1 deletion cli_createwallet.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package bc

import "fmt"

Expand Down
48 changes: 48 additions & 0 deletions cli_explore.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package bc
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure about this file and commands. Looks like its purpose is just to debug/test things.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep, this is some cli commands which helps me to understand the blockchain:-)


import (
"crypto/elliptic"
"encoding/hex"
"fmt"
)

func (cli *CLI) getPubKey(privateKey string) {
curve := elliptic.P256()
priv_key, _ := hex.DecodeString(privateKey)
x, y := curve.ScalarBaseMult(priv_key)
pubKey := append(x.Bytes(), y.Bytes()...)
fmt.Println(hex.EncodeToString(pubKey))
}

func (cli *CLI) generatePrivKey() {
private, _ := newKeyPair()
fmt.Println(hex.EncodeToString(private.D.Bytes()))
}

func (cli *CLI) getAddress(pubKey string) {
public, _ := hex.DecodeString(pubKey)

pubKeyHash := HashPubKey(public)

versionedPayload := append([]byte{version}, pubKeyHash...)
fullPayload := append(versionedPayload, checksum(versionedPayload)...)

fmt.Println()
fmt.Printf("PubKey : %s\n", pubKey)
fmt.Printf("PubKeyHash : %x\n", pubKeyHash)
fmt.Printf("Address : %s\n", Base58Encode(fullPayload))
}

func (cli *CLI) getPubKeyHash(address string) {
pubKeyHash := Base58Decode([]byte(address))
fmt.Printf("%x\n", pubKeyHash[1:len(pubKeyHash)-4])
}

func (cli *CLI) validateAddr(address string) {
fmt.Printf("Address: %s\n", address)
if !ValidateAddress(address) {
fmt.Println("Not valid!")
} else {
fmt.Println("Valid!")
}
}
2 changes: 1 addition & 1 deletion cli_getbalance.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package bc

import (
"fmt"
Expand Down
2 changes: 1 addition & 1 deletion cli_listaddress.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package bc

import (
"fmt"
Expand Down
33 changes: 32 additions & 1 deletion cli_printchain.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package main
package bc

import (
"fmt"
"strconv"
"time"
)

func (cli *CLI) printChain(nodeID string) {
Expand All @@ -17,6 +18,7 @@ func (cli *CLI) printChain(nodeID string) {
fmt.Printf("============ Block %x ============\n", block.Hash)
fmt.Printf("Height: %d\n", block.Height)
fmt.Printf("Prev. block: %x\n", block.PrevBlockHash)
fmt.Printf("Created at : %s\n", time.Unix(block.Timestamp, 0))
pow := NewProofOfWork(block)
fmt.Printf("PoW: %s\n\n", strconv.FormatBool(pow.Validate()))
for _, tx := range block.Transactions {
Expand All @@ -29,3 +31,32 @@ func (cli *CLI) printChain(nodeID string) {
}
}
}

func (cli *CLI) printBlock(blockHash, nodeID string) {
bc := NewBlockchain(nodeID)
defer bc.db.Close()

bci := bc.Iterator()

for {
block := bci.Next()

hash := fmt.Sprintf("%x", block.Hash)
if hash == blockHash {
fmt.Printf("============ Block %x ============\n", block.Hash)
fmt.Printf("Height: %d\n", block.Height)
fmt.Printf("Prev. block: %x\n", block.PrevBlockHash)
fmt.Printf("Created at : %s\n", time.Unix(block.Timestamp, 0))
pow := NewProofOfWork(block)
fmt.Printf("PoW: %s\n\n", strconv.FormatBool(pow.Validate()))
for _, tx := range block.Transactions {
fmt.Println(tx)
}
fmt.Printf("\n\n")
}

if len(block.PrevBlockHash) == 0 {
break
}
}
}
2 changes: 1 addition & 1 deletion cli_reindexutxo.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package bc

import "fmt"

Expand Down
8 changes: 6 additions & 2 deletions cli_send.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package bc

import (
"fmt"
Expand All @@ -22,8 +22,12 @@ func (cli *CLI) send(from, to string, amount int, nodeID string, mineNow bool) {
log.Panic(err)
}
wallet := wallets.GetWallet(from)
if wallet == nil {
fmt.Println("The Address doesn't belongs to you!")
return
}

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

if mineNow {
cbTx := NewCoinbaseTX(from, "")
Expand Down
2 changes: 1 addition & 1 deletion cli_startnode.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package bc

import (
"fmt"
Expand Down
6 changes: 0 additions & 6 deletions main.go

This file was deleted.

Loading