first commit

This commit is contained in:
arnaucode
2018-01-27 00:13:41 +01:00
parent 682fe68b0e
commit 51e2d00603
24 changed files with 1034 additions and 0 deletions

View File

@@ -0,0 +1,20 @@
package blockchainlib
import (
"crypto/sha256"
"encoding/base64"
"encoding/json"
"log"
)
func HashBlock(b Block) string {
blockJson, err := json.Marshal(b)
if err != nil {
log.Println(err)
}
blockString := string(blockJson)
h := sha256.New()
h.Write([]byte(blockString))
return base64.URLEncoding.EncodeToString(h.Sum(nil))
}

View File

@@ -0,0 +1,155 @@
package blockchainlib
import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"net/http"
"time"
"github.com/fatih/color"
)
type Block struct {
Hash string `json:"hash"`
Height int64 `json:"height"`
Date time.Time `json:"date"`
PreviousHash string `json:"previoushash"`
NextHash string `json:"nexthash"`
Data []string `json:"data"`
Emitter string `json:"emitter"` //the ID of the peer that has emmited the block
}
type Blockchain struct {
GenesisBlock string `json:"genesisblock"`
LastUpdate time.Time `json:"lastupdate"`
Blocks []Block `json:"blocks"`
}
//var blockchain Blockchain
func (bc *Blockchain) GetBlockByHash(hash string) (Block, error) {
for _, block := range bc.Blocks {
if block.Hash == hash {
return block, nil
}
}
var b Block
return b, errors.New("Block Hash not found")
}
func (bc *Blockchain) CreateBlock(data string) Block {
var b Block
b.Height = int64(len(bc.Blocks))
if len(bc.Blocks) == 0 {
b.Height = 0
} else {
b.PreviousHash = bc.Blocks[len(bc.Blocks)-1].Hash
}
b.Date = time.Now()
b.Data = append(b.Data, data)
//b.Emitter = runningPeer.ID
b.Hash = HashBlock(b)
return b
}
func (bc *Blockchain) BlockExists(block Block) bool {
for _, b := range bc.Blocks {
if b.Hash == block.Hash {
return true
}
}
return false
}
func (bc *Blockchain) AddBlock(block Block) error {
if bc.BlockExists(block) {
return errors.New("[Error adding Block]: Block already exists in the Blockchain")
}
if len(bc.Blocks) > 0 {
bc.Blocks[len(bc.Blocks)-1].NextHash = block.Hash
} else {
bc.GenesisBlock = block.Hash
}
bc.Blocks = append(bc.Blocks, block)
bc.SaveToDisk()
return nil
}
func (bc *Blockchain) ReconstructBlockchainFromBlock(urlAPI string, h string) {
color.Yellow("reconstructing the blockchain from last block in memory")
var block Block
var err error
block, err = bc.GetBlockByHash(h)
check(err)
if h == "" {
//no genesis block yet
color.Green(urlAPI + "/blocks/genesis")
res, err := http.Get(urlAPI + "/blocks/genesis")
check(err)
body, err := ioutil.ReadAll(res.Body)
check(err)
err = json.Unmarshal(body, &block)
check(err)
color.Yellow("[New Block]: " + block.Hash)
err = bc.AddBlock(block)
check(err)
} else {
block.NextHash = h
}
for block.NextHash != "" && block.Hash != "" {
res, err := http.Get(urlAPI + "/blocks/next/" + block.Hash)
check(err)
body, err := ioutil.ReadAll(res.Body)
check(err)
err = json.Unmarshal(body, &block)
check(err)
if block.Hash != "" {
color.Yellow("[New Block]: " + block.Hash)
err = bc.AddBlock(block)
check(err)
}
}
bc.Print()
}
func (bc *Blockchain) Print() {
color.Green("Printing Blockchain stored in memory")
color.Green("Genesis Block: " + bc.GenesisBlock)
for _, b := range bc.Blocks {
color.Green("Block height:")
fmt.Println(b.Height)
color.Green("Hash: " + b.Hash)
color.Green("Date: " + b.Date.String())
color.Green("---")
}
}
func (bc *Blockchain) ReadFromDisk() error {
file, err := ioutil.ReadFile("blockchain.data")
if err != nil {
return err
}
content := string(file)
json.Unmarshal([]byte(content), &bc)
return nil
}
func (bc *Blockchain) SaveToDisk() error {
bytesBlockchain, err := json.Marshal(bc)
if err != nil {
return err
}
err = ioutil.WriteFile("blockchain.data", bytesBlockchain, 0644)
if err != nil {
return err
}
return nil
}

View File

@@ -0,0 +1,15 @@
package blockchainlib
import (
"log"
"runtime"
)
func check(err error) {
if err != nil {
_, fn, line, _ := runtime.Caller(1)
log.Println(line)
log.Println(fn)
log.Println(err)
}
}