arnaucube
arnaucube/blockchainIDsystemPublic Self-hosted repository
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}