blockchainIDsystem/serverCA/blockchain.go
serverCA/blockchain.goRaw
1package main
2
3import (
4 "encoding/json"
5 "errors"
6 "fmt"
7 "io/ioutil"
8 "net/http"
9 "time"
10
11 "github.com/fatih/color"
12)
13
14type Block struct {
15 Hash string `json:"hash"`
16 Height int64 `json:"height"`
17 Date time.Time `json:"date"`
18 PreviousHash string `json:"previoushash"`
19 NextHash string `json:"nexthash"`
20 Data []Address `json:"data"`
21 Emitter string `json:"emitter"` //the ID of the peer that has emmited the block
22}
23
24type Blockchain struct {
25 GenesisBlock string `json:"genesisblock"`
26 LastUpdate time.Time `json:"lastupdate"`
27 Blocks []Block `json:"blocks"`
28}
29
30var blockchain Blockchain
31
32func (bc *Blockchain) getBlockByHash(hash string) (Block, error) {
33 for _, block := range bc.Blocks {
34 if block.Hash == hash {
35 return block, nil
36 }
37 }
38 var b Block
39 return b, errors.New("Block Hash not found")
40}
41
42func (bc *Blockchain) blockExists(block Block) bool {
43 for _, b := range bc.Blocks {
44 if b.Hash == block.Hash {
45 return true
46 }
47 }
48 return false
49}
50
51func (bc *Blockchain) addBlock(block Block) error {
52 if blockchain.blockExists(block) {
53 return errors.New("[Error adding Block]: Block already exists in the Blockchain")
54 }
55 if len(bc.Blocks) > 0 {
56 bc.Blocks[len(bc.Blocks)-1].NextHash = block.Hash
57 } else {
58 bc.GenesisBlock = block.Hash
59 }
60 bc.Blocks = append(bc.Blocks, block)
61
62 return nil
63}
64
65func reconstructBlockchainFromBlock(urlAPI string, h string) {
66 color.Yellow("reconstructing the blockchain from last block in memory")
67 var block Block
68 var err error
69
70 block, err = blockchain.getBlockByHash(h)
71 if err != nil {
72 fmt.Println("reconstructBlockFromBlock: block with " + h + " not found. Getting genesis block")
73 }
74
75 if h == "" {
76 //no genesis block yet
77 color.Green(urlAPI + "/blocks/genesis")
78 res, err := http.Get(urlAPI + "/blocks/genesis")
79 check(err)
80 body, err := ioutil.ReadAll(res.Body)
81 check(err)
82 err = json.Unmarshal(body, &block)
83 check(err)
84 color.Yellow("[New Block]: " + block.Hash)
85 err = blockchain.addBlock(block)
86 check(err)
87 } else {
88 block.NextHash = h
89 }
90
91 for block.NextHash != "" && block.Hash != "" {
92 res, err := http.Get(urlAPI + "/blocks/next/" + block.Hash)
93 check(err)
94 body, err := ioutil.ReadAll(res.Body)
95 check(err)
96 err = json.Unmarshal(body, &block)
97 check(err)
98 if block.Hash != "" {
99 color.Yellow("[New Block]: " + block.Hash)
100 err = blockchain.addBlock(block)
101 check(err)
102 }
103 }
104 blockchain.print()
105}
106
107func (bc *Blockchain) print() {
108 color.Green("Printing Blockchain stored in memory")
109 color.Green("Genesis Block: " + bc.GenesisBlock)
110 for _, b := range bc.Blocks {
111 color.Green("Block height:")
112 fmt.Println(b.Height)
113 color.Green("Hash: " + b.Hash)
114 color.Green("Date: " + b.Date.String())
115 color.Green("---")
116 }
117}