From b28cda243937471ce0c76837e37d5cbba1b44437 Mon Sep 17 00:00:00 2001 From: arnaucube Date: Sat, 6 Apr 2019 23:04:05 +0200 Subject: [PATCH] block structure & calculate PoW nonce --- README.md | 2 ++ core/block.go | 73 ++++++++++++++++++++++++++++++++++++++++++++++ core/block_test.go | 68 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 143 insertions(+) create mode 100644 core/block.go create mode 100644 core/block_test.go diff --git a/README.md b/README.md index 08c77ba..a17bf34 100644 --- a/README.md +++ b/README.md @@ -2,4 +2,6 @@ Slow, decentralized and cryptographically consistent database +Basically this repo is a blockchain written from scratch, that allows to launch multiple simultaneous blockchains. The motivation of this project is to fill the empty hours during a travel. + ![slowloris](https://04019a5a-a-62cb3a1a-s-sites.googlegroups.com/site/jchristensensdigitalportfolio/slow-loris/IO-moth-eating-frozen-apple-sauce.jpg "slowloris") diff --git a/core/block.go b/core/block.go new file mode 100644 index 0000000..fa3233e --- /dev/null +++ b/core/block.go @@ -0,0 +1,73 @@ +package core + +import ( + "encoding/json" + "time" +) + +type Input struct { +} +type Output struct { +} + +// Tx holds the data structure of a transaction +type Tx struct { + From Address + To Address + InputCount uint64 + Inputs []Input + Outputs []Output +} + +func NewTx(from, to Address, in []Input, out []Output) *Tx { + tx := &Tx{ + From: from, + To: to, + InputCount: uint64(len(in)), + Inputs: in, + Outputs: out, + } + return tx +} + +// Block holds the data structure for the block +type Block struct { + Height uint64 + PrevHash Hash + NextHash Hash + Txs []Tx + Miner Address + Timestamp time.Time + Nonce uint64 + Hash Hash + Signature []byte +} + +// Bytes outputs a byte array containing the data of the Block +func (blk Block) Bytes() []byte { + b, _ := json.Marshal(blk) + return b +} + +func (blk *Block) GetNonce() uint64 { + return blk.Nonce +} + +func (blk *Block) IncrementNonce() { + blk.Nonce++ +} +func (block *Block) CalculatePoW(difficulty int) error { + hash := HashBytes(block.Bytes()) + for !CheckPoW(hash, difficulty) { + block.IncrementNonce() + hash = HashBytes(block.Bytes()) + } + block.Hash = hash + return nil +} + +func BlockFromBytes(b []byte) (*Block, error) { + var block *Block + err := json.Unmarshal(b, &block) + return block, err +} diff --git a/core/block_test.go b/core/block_test.go new file mode 100644 index 0000000..357766a --- /dev/null +++ b/core/block_test.go @@ -0,0 +1,68 @@ +package core + +import ( + "testing" + "time" + + "github.com/stretchr/testify/assert" +) + +func TestBlock(t *testing.T) { + block := &Block{ + PrevHash: HashBytes([]byte("prevhash")), + NextHash: HashBytes([]byte("nextHash")), + Txs: []Tx{}, + Miner: Address(HashBytes([]byte("addrfromminer"))), + Timestamp: time.Now(), + Nonce: 0, + Hash: HashBytes([]byte("blockhash")), + } + + block, err := BlockFromBytes(block.Bytes()) + assert.Nil(t, err) + assert.Equal(t, block.Bytes(), block.Bytes()) + + difficulty := 2 + nonce, err := CalculatePoW(block, difficulty) + assert.Nil(t, err) + block.Nonce = nonce + h := HashBytes(block.Bytes()) + + // CheckPoW + assert.True(t, CheckPoW(h, difficulty)) +} + +func TestNewBlock(t *testing.T) { + block := &Block{ + PrevHash: HashBytes([]byte("prevhash")), + NextHash: HashBytes([]byte("nextHash")), + Txs: []Tx{}, + Miner: Address(HashBytes([]byte("addrfromminer"))), + Timestamp: time.Now(), + Nonce: 0, + Hash: HashBytes([]byte("blockhash")), + } + + block2, err := BlockFromBytes(block.Bytes()) + assert.Nil(t, err) + assert.Equal(t, block2.Bytes(), block.Bytes()) + + difficulty := 2 + nonce, err := CalculatePoW(block, difficulty) + assert.Nil(t, err) + block.Nonce = nonce + h := HashBytes(block.Bytes()) + + // CheckPoW + assert.True(t, CheckPoW(h, difficulty)) +} + +func TestTx(t *testing.T) { + addr0 := Address(HashBytes([]byte("addr0"))) + addr1 := Address(HashBytes([]byte("addr1"))) + + tx := NewTx(addr0, addr1, []Input{}, []Output{}) + + assert.Equal(t, tx.From, addr0) + assert.Equal(t, tx.To, addr1) +}