Browse Source

CreateGenesisBlock make tx, continue node test

master
arnaucube 5 years ago
parent
commit
c5893128ac
4 changed files with 137 additions and 10 deletions
  1. +14
    -1
      core/blockchain.go
  2. +23
    -2
      core/tx.go
  3. +36
    -2
      node/node.go
  4. +64
    -5
      node/node_test.go

+ 14
- 1
core/blockchain.go

@ -143,7 +143,20 @@ func (bc *Blockchain) VerifyBlock(block *Block) bool {
return false return false
} }
// verify block transactions
// verify block transactions (not if the block is the genesis block)
if !bytes.Equal(block.Txs[0].TxId[:], GenesisHashTxInput[:]) {
for _, tx := range block.Txs {
txVerified := CheckTx(&tx)
if !txVerified {
fmt.Println("tx could not be verified")
return false
}
}
}
// TODO in --> out0
// -> out1
// -> ...
return true return true
} }

+ 23
- 2
core/tx.go

@ -1,6 +1,12 @@
package core package core
import "crypto/ecdsa"
import (
"crypto/ecdsa"
"encoding/json"
"fmt"
)
var GenesisHashTxInput = HashBytes([]byte("genesis"))
type Input struct { type Input struct {
TxId Hash TxId Hash
@ -14,6 +20,7 @@ type Output struct {
// Tx holds the data structure of a transaction // Tx holds the data structure of a transaction
type Tx struct { type Tx struct {
TxId Hash
From *ecdsa.PublicKey From *ecdsa.PublicKey
To *ecdsa.PublicKey To *ecdsa.PublicKey
InputCount uint64 InputCount uint64
@ -22,6 +29,17 @@ type Tx struct {
Signature []byte Signature []byte
} }
func (tx *Tx) Bytes() []byte {
// TODO add parser, to use minimum amount of bytes
b, _ := json.Marshal(tx)
return b
}
func (tx *Tx) CalculateTxId() {
h := HashBytes(tx.Bytes())
tx.TxId = h
}
func NewTx(from, to *ecdsa.PublicKey, in []Input, out []Output) *Tx { func NewTx(from, to *ecdsa.PublicKey, in []Input, out []Output) *Tx {
tx := &Tx{ tx := &Tx{
From: from, From: from,
@ -29,7 +47,9 @@ func NewTx(from, to *ecdsa.PublicKey, in []Input, out []Output) *Tx {
InputCount: uint64(len(in)), InputCount: uint64(len(in)),
Inputs: in, Inputs: in,
Outputs: out, Outputs: out,
Signature: []byte{},
} }
tx.CalculateTxId()
return tx return tx
} }
@ -46,7 +66,8 @@ func CheckTx(tx *Tx) bool {
for _, out := range tx.Outputs { for _, out := range tx.Outputs {
totalOut = totalOut + int(out.Value) totalOut = totalOut + int(out.Value)
} }
if totalIn < totalOut {
if totalIn != totalOut {
fmt.Println("totalIn != totalOut")
return false return false
} }

+ 36
- 2
node/node.go

@ -85,11 +85,45 @@ func (node *Node) NewBlock(txs []core.Tx) (*core.Block, error) {
return block, nil return block, nil
} }
func (node *Node) CreateGenesis() (*core.Block, error) {
func (node *Node) CreateGenesis(pubK *ecdsa.PublicKey, amount uint64) (*core.Block, error) {
// pubK is the wallet where the first coins will be created
// amount is the amount of coins that will be created
in := core.Input{
TxId: core.GenesisHashTxInput,
Vout: 0,
Value: amount,
}
var ins []core.Input
ins = append(ins, in)
out := core.Output{
Value: amount,
}
var outs []core.Output
outs = append(outs, out)
tx := core.Tx{
From: &ecdsa.PublicKey{},
To: pubK,
InputCount: uint64(0),
Inputs: []core.Input{},
Outputs: outs,
Signature: []byte{},
}
// calculate TxId
// tx.CalculateTxId()
tx.TxId = core.GenesisHashTxInput
// sign transaction
var txs []core.Tx
txs = append(txs, tx)
block := &core.Block{ block := &core.Block{
Height: node.Bc.LastBlock.Height + 1, Height: node.Bc.LastBlock.Height + 1,
PrevHash: node.Bc.LastBlock.Hash, PrevHash: node.Bc.LastBlock.Hash,
Txs: []core.Tx{},
Txs: txs,
Miner: node.Addr, Miner: node.Addr,
MinerPubK: &node.PrivK.PublicKey, MinerPubK: &node.PrivK.PublicKey,
Timestamp: time.Now(), Timestamp: time.Now(),

+ 64
- 5
node/node_test.go

@ -122,22 +122,81 @@ func TestFromGenesisToTenBlocks(t *testing.T) {
assert.Nil(t, err) assert.Nil(t, err)
// create the genesis block // create the genesis block
genesisBlock, err := node.CreateGenesis()
genesisBlock, err := node.CreateGenesis(&privK.PublicKey, uint64(100))
assert.Nil(t, err) assert.Nil(t, err)
assert.NotEqual(t, genesisBlock.Signature, core.Signature{}) assert.NotEqual(t, genesisBlock.Signature, core.Signature{})
assert.NotEqual(t, genesisBlock.Hash, core.Hash{}) assert.NotEqual(t, genesisBlock.Hash, core.Hash{})
assert.True(t, node.Bc.VerifyBlock(genesisBlock)) assert.True(t, node.Bc.VerifyBlock(genesisBlock))
// add the genesis block into the blockchain // add the genesis block into the blockchain
err = node.Bc.AddBlock(genesisBlock) err = node.Bc.AddBlock(genesisBlock)
assert.Nil(t, err) assert.Nil(t, err)
assert.NotEqual(t, genesisBlock.Hash, core.Hash{}) assert.NotEqual(t, genesisBlock.Hash, core.Hash{})
assert.Equal(t, genesisBlock.Hash, node.Bc.LastBlock.Hash) assert.Equal(t, genesisBlock.Hash, node.Bc.LastBlock.Hash)
// TODO add another block
block, err := node.NewBlock([]core.Tx{})
// add another tx sending coins to the pubK0
privK0, err := core.NewKey()
assert.Nil(t, err)
pubK0 := privK0.PublicKey
var ins []core.Input
in := core.Input{
TxId: genesisBlock.Txs[0].TxId,
Vout: 0,
Value: 100,
}
ins = append(ins, in)
var outs []core.Output
out0 := core.Output{
Value: 10,
}
out1 := core.Output{
Value: 90,
}
outs = append(outs, out0)
outs = append(outs, out1)
tx := core.NewTx(&privK.PublicKey, &pubK0, ins, outs)
// verify tx
txVerified := core.CheckTx(tx)
assert.True(t, txVerified)
// then create a new block with the tx and add it to the blockchain
var txs []core.Tx
txs = append(txs, *tx)
block, err := node.NewBlock(txs)
assert.Nil(t, err)
err = node.Bc.AddBlock(block)
assert.Nil(t, err)
// add another tx sending coins to the pubK1
privK1, err := core.NewKey()
assert.Nil(t, err)
pubK1 := privK1.PublicKey
ins = []core.Input{}
in = core.Input{
TxId: block.Txs[0].TxId,
Vout: 0,
Value: 10,
}
ins = append(ins, in)
outs = []core.Output{}
out0 = core.Output{
Value: 10,
}
outs = append(outs, out0)
tx = core.NewTx(&pubK0, &pubK1, ins, outs)
// verify tx
txVerified = core.CheckTx(tx)
assert.True(t, txVerified)
// then create a new block with the tx and add it to the blockchain
txs = []core.Tx{}
txs = append(txs, *tx)
block, err = node.NewBlock(txs)
assert.Nil(t, err) assert.Nil(t, err)
block.Print()
err = node.Bc.AddBlock(block) err = node.Bc.AddBlock(block)
assert.Nil(t, err) assert.Nil(t, err)
} }

Loading…
Cancel
Save