CreateGenesisBlock make tx, continue node test
arnaucube arnaucube@gmail.com
Wed, 10 Apr 2019 16:43:04 +0200
4 files changed,
137 insertions(+),
10 deletions(-)
M
core/blockchain.go
→
core/blockchain.go
@@ -143,7 +143,20 @@ fmt.Println("block.Height error")
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 }
M
core/tx.go
→
core/tx.go
@@ -1,6 +1,12 @@
package core -import "crypto/ecdsa" +import ( + "crypto/ecdsa" + "encoding/json" + "fmt" +) + +var GenesisHashTxInput = HashBytes([]byte("genesis")) type Input struct { TxId Hash@@ -14,6 +20,7 @@ }
// Tx holds the data structure of a transaction type Tx struct { + TxId Hash From *ecdsa.PublicKey To *ecdsa.PublicKey InputCount uint64@@ -22,6 +29,17 @@ Outputs []Output
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 { tx := &Tx{ From: from,@@ -29,7 +47,9 @@ To: to,
InputCount: uint64(len(in)), Inputs: in, Outputs: out, + Signature: []byte{}, } + tx.CalculateTxId() return tx }@@ -46,7 +66,8 @@ totalOut := 0
for _, out := range tx.Outputs { totalOut = totalOut + int(out.Value) } - if totalIn < totalOut { + if totalIn != totalOut { + fmt.Println("totalIn != totalOut") return false }
M
node/node.go
→
node/node.go
@@ -85,11 +85,45 @@ }
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{ Height: node.Bc.LastBlock.Height + 1, PrevHash: node.Bc.LastBlock.Hash, - Txs: []core.Tx{}, + Txs: txs, Miner: node.Addr, MinerPubK: &node.PrivK.PublicKey, Timestamp: time.Now(),
M
node/node_test.go
→
node/node_test.go
@@ -122,22 +122,81 @@ node, err := NewNode(privK, bc, true)
assert.Nil(t, err) // create the genesis block - genesisBlock, err := node.CreateGenesis() + genesisBlock, err := node.CreateGenesis(&privK.PublicKey, uint64(100)) assert.Nil(t, err) assert.NotEqual(t, genesisBlock.Signature, core.Signature{}) 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 err = node.Bc.AddBlock(genesisBlock) assert.Nil(t, err) assert.NotEqual(t, genesisBlock.Hash, core.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) - block.Print() + 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) err = node.Bc.AddBlock(block) assert.Nil(t, err) }