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 check(err)
72
73 if h == "" {
74 //no genesis block yet
75 color.Green(urlAPI + "/blocks/genesis")
76 res, err := http.Get(urlAPI + "/blocks/genesis")
77 check(err)
78 body, err := ioutil.ReadAll(res.Body)
79 check(err)
80 err = json.Unmarshal(body, &block)
81 check(err)
82 color.Yellow("[New Block]: " + block.Hash)
83 err = blockchain.addBlock(block)
84 check(err)
85 } else {
86 block.NextHash = h
87 }
88
89 for block.NextHash != "" && block.Hash != "" {
90 res, err := http.Get(urlAPI + "/blocks/next/" + block.Hash)
91 check(err)
92 body, err := ioutil.ReadAll(res.Body)
93 check(err)
94 err = json.Unmarshal(body, &block)
95 check(err)
96 if block.Hash != "" {
97 color.Yellow("[New Block]: " + block.Hash)
98 err = blockchain.addBlock(block)
99 check(err)
100 }
101 }
102 blockchain.print()
103}
104
105func (bc *Blockchain) print() {
106 color.Green("Printing Blockchain stored in memory")
107 color.Green("Genesis Block: " + bc.GenesisBlock)
108 for _, b := range bc.Blocks {
109 color.Green("Block height:")
110 fmt.Println(b.Height)
111 color.Green("Hash: " + b.Hash)
112 color.Green("Date: " + b.Date.String())
113 color.Green("---")
114 }
115}