diff --git a/.gitignore b/.gitignore index d3beee5..7a2c58a 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,5 @@ _testmain.go *.test *.prof +# And the binary +blockchain-poc diff --git a/block.go b/block.go new file mode 100644 index 0000000..eb45918 --- /dev/null +++ b/block.go @@ -0,0 +1,31 @@ +package main + +import ( + "bytes" + "crypto/sha256" + "strconv" + "time" +) + +type Block struct { + Timestamp int64 + Data []byte + PrevBlockHash []byte + Hash []byte +} + +// NewBlock returns a new block, ready to be added to the chain +func NewBlock(data string, prevBlockHash []byte) *Block { + block := &Block{time.Now().Unix(), []byte(data), prevBlockHash, []byte{}} + block.SetHash() + return block +} + +// SetHash creates the block hash +func (b *Block) SetHash() { + timestamp := []byte(strconv.FormatInt(b.Timestamp, 10)) + headers := bytes.Join([][]byte{b.PrevBlockHash, b.Data, timestamp}, []byte{}) + hash := sha256.Sum256(headers) + + b.Hash = hash[:] +} diff --git a/blockchain.go b/blockchain.go new file mode 100644 index 0000000..6b7dfb2 --- /dev/null +++ b/blockchain.go @@ -0,0 +1,21 @@ +package main + +type Blockchain struct { + blocks []*Block +} + +func NewBlockchain() *Blockchain { + return &Blockchain{[]*Block{NewGenesisBlock()}} +} + +// NewGenesisBlock creates a new Genesis Block to start the blockchain +func NewGenesisBlock() *Block { + return NewBlock("Genesis Block", []byte{}) +} + +// AddBlock adds a block to the blockchain +func (bc *Blockchain) AddBlock(data string) { + prevBlock := bc.blocks[len(bc.blocks)-1] + newBlock := NewBlock(data, prevBlock.Hash) + bc.blocks = append(bc.blocks, newBlock) +} diff --git a/main.go b/main.go new file mode 100644 index 0000000..fa0f855 --- /dev/null +++ b/main.go @@ -0,0 +1,16 @@ +package main + +import "fmt" + +func main() { + bc := NewBlockchain() + bc.AddBlock("Data 1") + bc.AddBlock("Data 2") + + for _, block := range bc.blocks { + fmt.Printf("Prev. hash: %x\n", block.PrevBlockHash) + fmt.Printf("Data: %s\n", block.Data) + fmt.Printf("Hash: %x\n", block.Hash) + fmt.Println() + } +}