block.go 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. /*
  2. Copyright © 2021-2022 Ettore Di Giacinto <[email protected]>
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package blockchain
  14. import (
  15. "crypto/sha256"
  16. "encoding/hex"
  17. "fmt"
  18. "time"
  19. )
  20. type DataString string
  21. // Block represents each 'item' in the blockchain
  22. type Block struct {
  23. Index int
  24. Timestamp string
  25. Storage map[string]map[string]Data
  26. Hash string
  27. PrevHash string
  28. }
  29. // Blockchain is a series of validated Blocks
  30. type Blockchain []Block
  31. // make sure block is valid by checking index, and comparing the hash of the previous block
  32. func (newBlock Block) IsValid(oldBlock Block) bool {
  33. if oldBlock.Index+1 != newBlock.Index {
  34. return false
  35. }
  36. if oldBlock.Hash != newBlock.PrevHash {
  37. return false
  38. }
  39. if newBlock.Checksum() != newBlock.Hash {
  40. return false
  41. }
  42. return true
  43. }
  44. // Checksum does SHA256 hashing of the block
  45. func (b Block) Checksum() string {
  46. record := fmt.Sprint(b.Index, b.Timestamp, b.Storage, b.PrevHash)
  47. h := sha256.New()
  48. h.Write([]byte(record))
  49. hashed := h.Sum(nil)
  50. return hex.EncodeToString(hashed)
  51. }
  52. // create a new block using previous block's hash
  53. func (oldBlock Block) NewBlock(s map[string]map[string]Data) Block {
  54. var newBlock Block
  55. t := time.Now().UTC()
  56. newBlock.Index = oldBlock.Index + 1
  57. newBlock.Timestamp = t.String()
  58. newBlock.Storage = s
  59. newBlock.PrevHash = oldBlock.Hash
  60. newBlock.Hash = newBlock.Checksum()
  61. return newBlock
  62. }