garritfra
6 years ago
14 changed files with 52 additions and 239 deletions
@ -1,3 +1,5 @@
|
||||
blockchain-project |
||||
.vscode/ |
||||
core/core |
||||
core/core |
||||
/target |
||||
**/*.rs.bk |
||||
|
@ -0,0 +1,4 @@
|
||||
[[package]] |
||||
name = "blockchain-project" |
||||
version = "0.1.0" |
||||
|
@ -0,0 +1,6 @@
|
||||
[package] |
||||
name = "blockchain-project" |
||||
version = "0.1.0" |
||||
authors = ["garritfra <garritfranke@gmail.com>"] |
||||
|
||||
[dependencies] |
@ -1,14 +0,0 @@
|
||||
package core |
||||
|
||||
import ( |
||||
"time" |
||||
) |
||||
|
||||
// Block Struct
|
||||
type Block struct { |
||||
Timestamp time.Time |
||||
Hash string |
||||
PreviousHash string |
||||
Data []Transaction |
||||
Nonce int |
||||
} |
@ -1,67 +0,0 @@
|
||||
package core |
||||
|
||||
import ( |
||||
"log" |
||||
"strings" |
||||
"time" |
||||
|
||||
"github.com/garritfra/blockchain-project/crypto" |
||||
) |
||||
|
||||
// Blockchain struct
|
||||
type Blockchain struct { |
||||
Blocks []Block |
||||
PendingTransactions []Transaction |
||||
} |
||||
|
||||
// MineBlock adds a block to the chain
|
||||
func (bc *Blockchain) MineBlock() Block { |
||||
block := Block{} |
||||
block.Data = bc.PendingTransactions |
||||
block.Timestamp = time.Now() |
||||
block.PreviousHash = bc.GetLastHash() |
||||
// Mine Block
|
||||
log.Print("Mining Block...") |
||||
for { |
||||
hash := crypto.CalculateHash(block) |
||||
if strings.HasPrefix(hash, "00000") { |
||||
block.Hash = hash |
||||
|
||||
bc.Blocks = append(bc.Blocks, block) |
||||
bc.PendingTransactions = []Transaction{} |
||||
|
||||
log.Print("Block Added: ", block.Hash) |
||||
return block |
||||
} |
||||
block.Nonce++ |
||||
} |
||||
|
||||
} |
||||
|
||||
// NewBlockchain creates a new Blockchain
|
||||
func NewBlockchain() Blockchain { |
||||
log.Print("Creating Blockchain...") |
||||
|
||||
blockchain := Blockchain{Blocks: make([]Block, 0), PendingTransactions: make([]Transaction, 0)} |
||||
|
||||
// Mine Genesis Block
|
||||
blockchain.MineBlock() |
||||
return blockchain |
||||
} |
||||
|
||||
// AddTransaction takes in a transaction and adds it to the block
|
||||
func (bc *Blockchain) AddTransaction(transaction Transaction) error { |
||||
bc.PendingTransactions = append(bc.PendingTransactions, transaction) |
||||
return nil |
||||
} |
||||
|
||||
// GetLastHash returns the hash of the latest block on the chain
|
||||
func (bc *Blockchain) GetLastHash() string { |
||||
|
||||
bcLength := len(bc.Blocks) |
||||
|
||||
if bcLength == 0 { |
||||
return "0" |
||||
} |
||||
return bc.Blocks[len(bc.Blocks)-1].Hash |
||||
} |
@ -1,9 +0,0 @@
|
||||
package core |
||||
|
||||
// Transaction struct
|
||||
type Transaction struct { |
||||
Sender string |
||||
Receiver string |
||||
Amount int |
||||
Message string |
||||
} |
@ -1,18 +0,0 @@
|
||||
package core |
||||
|
||||
import ( |
||||
"testing" |
||||
) |
||||
|
||||
func TestBlock_AddTransaction(t *testing.T) { |
||||
block := Block{} |
||||
transaction := Transaction{Sender: "foo", Receiver: "bar", Message: "Test", Amount: 100} |
||||
block.AddTransaction(transaction) |
||||
|
||||
want := transaction |
||||
got := block.Data[0] |
||||
|
||||
if want != got { |
||||
t.Errorf("Want: %v, but got %v", want, got) |
||||
} |
||||
} |
@ -1,32 +0,0 @@
|
||||
package core |
||||
|
||||
import ( |
||||
"testing" |
||||
) |
||||
|
||||
func Test_generateGenesisBlock(t *testing.T) { |
||||
genesisBlock := generateGenesisBlock() |
||||
|
||||
if len(genesisBlock.PreviousHash) > 1 { |
||||
t.Errorf("Previous hash of Genesis Block is not empty!") |
||||
} |
||||
} |
||||
|
||||
func TestNewBlockchain(t *testing.T) { |
||||
blockchain := NewBlockchain() |
||||
|
||||
if len(blockchain.Blocks) != 1 { |
||||
t.Errorf("New Blockchain has too many Blocks (Besides Genesis)") |
||||
} |
||||
} |
||||
|
||||
func TestBlockchain_GetLastHash(t *testing.T) { |
||||
blockchain := NewBlockchain() |
||||
|
||||
blockchain.MineBlock(Block{}) |
||||
want := blockchain.Blocks[1].Hash |
||||
got := blockchain.GetLastHash() |
||||
if got != want { |
||||
t.Errorf("Want: %v, but got %v", want, got) |
||||
} |
||||
} |
@ -1,23 +0,0 @@
|
||||
package crypto |
||||
|
||||
import ( |
||||
"bytes" |
||||
"crypto/sha256" |
||||
"encoding/gob" |
||||
"encoding/hex" |
||||
) |
||||
|
||||
func CalculateHash(obj interface{}) string { |
||||
var buffer bytes.Buffer |
||||
encoder := gob.NewEncoder(&buffer) |
||||
if err := encoder.Encode(obj); err != nil { |
||||
panic(err) |
||||
} |
||||
hasher := sha256.New() |
||||
bytes := buffer.Bytes() |
||||
hasher.Write(bytes) |
||||
|
||||
sum := hex.EncodeToString(hasher.Sum(nil)) |
||||
|
||||
return string(sum) |
||||
} |
@ -1,9 +0,0 @@
|
||||
package main |
||||
|
||||
import ( |
||||
"github.com/garritfra/blockchain-project/server" |
||||
) |
||||
|
||||
func main() { |
||||
server.ServeHTTP(":42000") |
||||
} |
@ -1,66 +0,0 @@
|
||||
package server |
||||
|
||||
import ( |
||||
"encoding/gob" |
||||
"encoding/json" |
||||
"log" |
||||
"net/http" |
||||
|
||||
"github.com/garritfra/blockchain-project/core" |
||||
) |
||||
|
||||
var blockchain core.Blockchain |
||||
|
||||
// ServeHTTP serves a http server on a given port with format ":PORT"
|
||||
func ServeHTTP(port string) { |
||||
gob.Register(core.Block{}) |
||||
gob.Register(core.Transaction{}) |
||||
gob.Register(core.Blockchain{}) |
||||
|
||||
blockchain = core.NewBlockchain() |
||||
|
||||
registerRouteHandlers() |
||||
|
||||
log.Print("Listening on port ", port) |
||||
if err := http.ListenAndServe(port, nil); err != nil { |
||||
panic(err) |
||||
} |
||||
} |
||||
|
||||
func registerRouteHandlers() { |
||||
http.HandleFunc("/", handleListBlocks) |
||||
http.HandleFunc("/mine_block", handleMineBlock) |
||||
http.HandleFunc("/pending_transactions", handleListPendingTransactions) |
||||
http.HandleFunc("/add_transaction", handleAddTransaction) |
||||
} |
||||
|
||||
func handleError(err error, w http.ResponseWriter, r *http.Request) { |
||||
w.Write([]byte("Error: " + err.Error())) |
||||
log.Print(err.Error()) |
||||
} |
||||
|
||||
func handleListBlocks(w http.ResponseWriter, r *http.Request) { |
||||
json.NewEncoder(w).Encode(blockchain.Blocks) |
||||
} |
||||
|
||||
func handleAddTransaction(w http.ResponseWriter, r *http.Request) { |
||||
decoder := json.NewDecoder(r.Body) |
||||
var receivedTransaction core.Transaction |
||||
err := decoder.Decode(&receivedTransaction) |
||||
if err == nil { |
||||
log.Println("Transaction from", receivedTransaction.Sender, "to", receivedTransaction.Receiver, "received") |
||||
|
||||
go blockchain.AddTransaction(receivedTransaction) |
||||
} else { |
||||
handleError(err, w, r) |
||||
} |
||||
} |
||||
|
||||
func handleMineBlock(w http.ResponseWriter, r *http.Request) { |
||||
block := blockchain.MineBlock() |
||||
json.NewEncoder(w).Encode(block) |
||||
} |
||||
|
||||
func handleListPendingTransactions(w http.ResponseWriter, r *http.Request) { |
||||
json.NewEncoder(w).Encode(blockchain.PendingTransactions) |
||||
} |
@ -0,0 +1,27 @@
|
||||
pub struct Block { |
||||
pub data: i32, |
||||
} |
||||
|
||||
pub struct Blockchain { |
||||
blocks: Vec<Block>, |
||||
} |
||||
pub fn new() -> Blockchain { |
||||
println!("New blockchain\n"); |
||||
|
||||
let genesis = Block { data: 32 }; |
||||
|
||||
let blockchain = Blockchain { |
||||
blocks: vec![genesis], |
||||
}; |
||||
return blockchain; |
||||
} |
||||
|
||||
impl Blockchain { |
||||
pub fn addBlock(&mut self, block: Block) { |
||||
self.blocks.push(block); |
||||
} |
||||
|
||||
pub fn getBlocks(&mut self) -> &Vec<Block> { |
||||
&self.blocks |
||||
} |
||||
} |
Loading…
Reference in new issue