Integrate transactions into the blockchain

This commit is contained in:
Ivan Kuznetsov 2017-09-03 09:45:49 +07:00
parent 2ba0f1bfdd
commit 08a211be41
4 changed files with 45 additions and 11 deletions

View File

@ -10,7 +10,7 @@ import (
// Block keeps block headers
type Block struct {
Timestamp int64
Data []byte
Transactions []*Transaction
PrevBlockHash []byte
Hash []byte
Nonce int
@ -30,8 +30,8 @@ func (b *Block) Serialize() []byte {
}
// NewBlock creates and returns Block
func NewBlock(data string, prevBlockHash []byte) *Block {
block := &Block{time.Now().Unix(), []byte(data), prevBlockHash, []byte{}, 0}
func NewBlock(transactions []*Transaction, prevBlockHash []byte) *Block {
block := &Block{time.Now().Unix(), transactions, prevBlockHash, []byte{}, 0}
pow := NewProofOfWork(block)
nonce, hash := pow.Run()
@ -42,8 +42,8 @@ func NewBlock(data string, prevBlockHash []byte) *Block {
}
// NewGenesisBlock creates and returns genesis Block
func NewGenesisBlock() *Block {
return NewBlock("Genesis Block", []byte{})
func NewGenesisBlock(coinbase *Transaction) *Block {
return NewBlock([]*Transaction{coinbase}, []byte{})
}
// DeserializeBlock deserializes a block

View File

@ -9,6 +9,7 @@ import (
const dbFile = "blockchain.db"
const blocksBucket = "blocks"
const genesisCoinbase = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks"
// Blockchain keeps a sequence of Blocks
type Blockchain struct {
@ -86,7 +87,7 @@ func (i *BlockchainIterator) Next() *Block {
}
// NewBlockchain creates a new Blockchain with genesis Block
func NewBlockchain() *Blockchain {
func NewBlockchain(address string) *Blockchain {
var tip []byte
db, err := bolt.Open(dbFile, 0600, nil)
if err != nil {
@ -98,7 +99,8 @@ func NewBlockchain() *Blockchain {
if b == nil {
fmt.Println("No existing blockchain found. Creating a new one...")
genesis := NewGenesisBlock()
cbtx := NewCoinbaseTX(address, genesisCoinbase)
genesis := NewGenesisBlock(cbtx)
b, err := tx.CreateBucket([]byte(blocksBucket))
if err != nil {

View File

@ -31,10 +31,18 @@ func NewProofOfWork(b *Block) *ProofOfWork {
}
func (pow *ProofOfWork) prepareData(nonce int) []byte {
var txHashes [][]byte
var txHash [32]byte
for _, tx := range pow.block.Transactions {
txHashes = append(txHashes, tx.GetHash())
}
txHash = sha256.Sum256(bytes.Join(txHashes, []byte{}))
data := bytes.Join(
[][]byte{
pow.block.PrevBlockHash,
pow.block.Data,
txHash[:],
IntToHex(pow.block.Timestamp),
IntToHex(int64(targetBits)),
IntToHex(int64(nonce)),

View File

@ -1,6 +1,11 @@
package main
import "log"
import (
"bytes"
"crypto/sha256"
"encoding/gob"
"log"
)
const subsidy = 10
@ -15,6 +20,21 @@ func (tx Transaction) IsCoinbase() bool {
return len(tx.Vin) == 1 && tx.Vin[0].Txid == -1 && tx.Vin[0].Vout == -1
}
// GetHash hashes the transaction and returns the hash
func (tx Transaction) GetHash() []byte {
var encoded bytes.Buffer
var hash [32]byte
enc := gob.NewEncoder(&encoded)
err := enc.Encode(tx)
if err != nil {
log.Panic(err)
}
hash = sha256.Sum256(encoded.Bytes())
return hash[:]
}
// TXInput represents a transaction input
type TXInput struct {
Txid int
@ -34,8 +54,12 @@ func (out *TXOutput) Unlock(unlockingData string) bool {
}
// NewCoinbaseTX creates a new coinbase transaction
func NewCoinbaseTX(to string) *Transaction {
txin := TXInput{-1, -1, "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks"}
func NewCoinbaseTX(to, data string) *Transaction {
if data == "" {
data = "Coinbase"
}
txin := TXInput{-1, -1, data}
txout := TXOutput{subsidy, to}
tx := Transaction{[]TXInput{txin}, []TXOutput{txout}}