aboutsummaryrefslogtreecommitdiff
path: root/pkg/block/block.go
diff options
context:
space:
mode:
authorgithub-classroom[bot] <66690702+github-classroom[bot]@users.noreply.github.com>2022-02-28 19:36:23 +0000
committergithub-classroom[bot] <66690702+github-classroom[bot]@users.noreply.github.com>2022-02-28 19:36:23 +0000
commit1dd0508d5d3c737f1ee9c723f580baf73b1cfd70 (patch)
tree6adcc5ef85f9cf0bbb205c577da0bac9148114dd /pkg/block/block.go
Initial commit
Diffstat (limited to 'pkg/block/block.go')
-rw-r--r--pkg/block/block.go90
1 files changed, 90 insertions, 0 deletions
diff --git a/pkg/block/block.go b/pkg/block/block.go
new file mode 100644
index 0000000..843f43f
--- /dev/null
+++ b/pkg/block/block.go
@@ -0,0 +1,90 @@
+package block
+
+import (
+ "Chain/pkg/pro"
+ "crypto/sha256"
+ "fmt"
+ "google.golang.org/protobuf/proto"
+)
+
+// Header provides information about the Block.
+// Version is the Block's version.
+// PreviousHash is the hash of the previous Block.
+// MerkleRoot is the hash of all the Block's Transactions.
+// DifficultyTarget is the difficulty of achieving a winning Nonce.
+// Nonce is a "number only used once" that satisfies the DifficultyTarget.
+// Timestamp is when the Block was successfully mined.
+type Header struct {
+ Version uint32
+ PreviousHash string
+ MerkleRoot string
+ DifficultyTarget string
+ Nonce uint32
+ Timestamp uint32
+}
+
+// Block includes a Header and a slice of Transactions.
+type Block struct {
+ Header *Header
+ Transactions []*Transaction
+}
+
+// EncodeHeader returns a pro.Header given a Header.
+func EncodeHeader(header *Header) *pro.Header {
+ return &pro.Header{
+ Version: header.Version,
+ PreviousHash: header.PreviousHash,
+ MerkleRoot: header.MerkleRoot,
+ DifficultyTarget: header.DifficultyTarget,
+ Nonce: header.Nonce,
+ Timestamp: header.Timestamp,
+ }
+}
+
+// DecodeHeader returns a Header given a pro.Header.
+func DecodeHeader(pheader *pro.Header) *Header {
+ return &Header{
+ Version: pheader.GetVersion(),
+ PreviousHash: pheader.GetPreviousHash(),
+ MerkleRoot: pheader.GetMerkleRoot(),
+ DifficultyTarget: pheader.GetDifficultyTarget(),
+ Nonce: pheader.GetNonce(),
+ Timestamp: pheader.GetTimestamp(),
+ }
+}
+
+// EncodeBlock returns a pro.Block given a Block.
+func EncodeBlock(b *Block) *pro.Block {
+ var ptxs []*pro.Transaction
+ for _, tx := range b.Transactions {
+ ptxs = append(ptxs, EncodeTransaction(tx))
+ }
+ return &pro.Block{
+ Header: EncodeHeader(b.Header),
+ Transactions: ptxs,
+ }
+}
+
+// DecodeBlock returns a Block given a pro.Block.
+func DecodeBlock(pb *pro.Block) *Block {
+ var txs []*Transaction
+ for _, ptx := range pb.GetTransactions() {
+ txs = append(txs, DecodeTransaction(ptx))
+ }
+ return &Block{
+ Header: DecodeHeader(pb.GetHeader()),
+ Transactions: txs,
+ }
+}
+
+// Hash returns the hash of the block (which is done via the header)
+func (block *Block) Hash() string {
+ h := sha256.New()
+ pb := EncodeHeader(block.Header)
+ bytes, err := proto.Marshal(pb)
+ if err != nil {
+ fmt.Errorf("[block.Hash()] Unable to marshal block")
+ }
+ h.Write(bytes)
+ return fmt.Sprintf("%x", h.Sum(nil))
+}