block structure & calculate PoW nonce

This commit is contained in:
arnaucube
2019-04-06 23:04:05 +02:00
parent 21f0d57fe4
commit b28cda2439
3 changed files with 143 additions and 0 deletions

73
core/block.go Normal file
View File

@@ -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
}

68
core/block_test.go Normal file
View File

@@ -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)
}