block.go 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. package blockchain
  2. import (
  3. "crypto/sha256"
  4. "encoding/hex"
  5. "fmt"
  6. "time"
  7. )
  8. type DataString string
  9. // Block represents each 'item' in the blockchain
  10. type Block struct {
  11. Index int
  12. Timestamp string
  13. Storage map[string]map[string]Data
  14. Hash string
  15. PrevHash string
  16. }
  17. // Blockchain is a series of validated Blocks
  18. type Blockchain []Block
  19. // make sure block is valid by checking index, and comparing the hash of the previous block
  20. func (newBlock Block) IsValid(oldBlock Block) bool {
  21. if oldBlock.Index+1 != newBlock.Index {
  22. return false
  23. }
  24. if oldBlock.Hash != newBlock.PrevHash {
  25. return false
  26. }
  27. if newBlock.Checksum() != newBlock.Hash {
  28. return false
  29. }
  30. return true
  31. }
  32. // Checksum does SHA256 hashing of the block
  33. func (b Block) Checksum() string {
  34. record := fmt.Sprint(b.Index, b.Timestamp, b.Storage, b.PrevHash)
  35. h := sha256.New()
  36. h.Write([]byte(record))
  37. hashed := h.Sum(nil)
  38. return hex.EncodeToString(hashed)
  39. }
  40. // create a new block using previous block's hash
  41. func (oldBlock Block) NewBlock(s map[string]map[string]Data) Block {
  42. var newBlock Block
  43. t := time.Now()
  44. newBlock.Index = oldBlock.Index + 1
  45. newBlock.Timestamp = t.String()
  46. newBlock.Storage = s
  47. newBlock.PrevHash = oldBlock.Hash
  48. newBlock.Hash = newBlock.Checksum()
  49. return newBlock
  50. }