You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

100 lines
2.4 KiB

package core
import (
"log"
"strings"
"time"
)
// Blockchain struct
type Blockchain struct {
Blocks []Block
PendingTransactions []Transaction
Peers []string
}
// MineBlock adds a block to the chain
func (bc *Blockchain) MineBlock() Block {
block := Block{}
block.Data = bc.PendingTransactions
block.Timestamp = time.Now()
block.PreviousHash = bc.GetLastHash()
// Mine Block
log.Print("Mining Block...")
for {
if strings.HasPrefix(block.Hash(), "0000") {
bc.Blocks = append(bc.Blocks, block)
bc.PendingTransactions = []Transaction{}
log.Print("Block Added: ", block.Hash())
return block
}
block.Proof++
}
}
// NewBlockchain creates a new Blockchain
func NewBlockchain() Blockchain {
log.Print("Creating Blockchain...")
blockchain := Blockchain{Blocks: make([]Block, 0), PendingTransactions: make([]Transaction, 0), Peers: make([]string, 0)}
// Mine Genesis Block
blockchain.MineBlock()
return blockchain
}
// AddTransaction takes in a transaction and adds it to the block
func (bc *Blockchain) AddTransaction(transaction Transaction) error {
bc.PendingTransactions = append(bc.PendingTransactions, transaction)
return nil
}
// GetLastHash returns the hash of the latest block on the chain
func (bc *Blockchain) GetLastHash() string {
bcLength := len(bc.Blocks)
if bcLength == 0 {
return "0"
}
return bc.Blocks[len(bc.Blocks)-1].Hash()
}
// AddPeer appends the IP address to the list of peers known to the chain
func (bc *Blockchain) AddPeer(peer string) {
bc.Peers = append(bc.Peers, peer)
}
// IsValid checks, if the chain has any faulty blocks
func (bc *Blockchain) IsValid() bool {
for i := 1; i < len(bc.Blocks); i++ {
if bc.Blocks[i-1].Hash() != bc.Blocks[i].PreviousHash {
return false
}
}
return true
}
// JSONBlockchain is needed, because the hash of each block is calculated dynamically, and therefore is not stored in the `Block` struct
type JSONBlockchain struct {
Blocks []JSONBlock
Blockcount int
PendingTransactions []Transaction
Peers []string
}
// AsJSON returns the Blockchain as a JSON Blockchain
func (bc *Blockchain) AsJSON() JSONBlockchain {
jsonChain := JSONBlockchain{PendingTransactions: bc.PendingTransactions, Peers: bc.Peers}
for _, block := range bc.Blocks {
jsonChain.Blocks = append(jsonChain.Blocks, block.AsJSON())
}
jsonChain.Blockcount = len(jsonChain.Blocks)
return jsonChain
}