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.

70 lines
1.5 KiB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
  1. package core
  2. import (
  3. "bytes"
  4. "crypto/sha256"
  5. "encoding/binary"
  6. "encoding/hex"
  7. )
  8. // Hash is the type for a hash data packet
  9. type Hash [32]byte
  10. // IsZero returns true if the Hash is empty (all zeroes)
  11. func (h *Hash) IsZero() bool {
  12. z := Hash{}
  13. if bytes.Equal(z[:], h[:]) {
  14. return true
  15. }
  16. return false
  17. }
  18. func (h *Hash) String() string {
  19. return hex.EncodeToString(h[:])
  20. }
  21. // HashBytes performs a hash over a given byte array
  22. func HashBytes(b []byte) Hash {
  23. h := sha256.Sum256(b)
  24. return h
  25. }
  26. // PoWData is the interface for the data that have the Nonce parameter to calculate the Proof-of-Work
  27. type PoWData interface {
  28. Bytes() []byte
  29. GetNonce() uint64
  30. IncrementNonce()
  31. }
  32. // CheckPoW verifies the PoW difficulty of a Hash
  33. func CheckPoW(hash Hash, difficulty uint64) bool {
  34. var empty [32]byte
  35. if !bytes.Equal(hash[:][0:difficulty], empty[0:difficulty]) {
  36. return false
  37. }
  38. return true
  39. }
  40. // CalculatePoW calculates the nonce for the given data in order to fit in the current Proof of Work difficulty
  41. func CalculatePoW(data PoWData, difficulty uint64) (uint64, error) {
  42. hash := HashBytes(data.Bytes())
  43. for !CheckPoW(hash, difficulty) {
  44. data.IncrementNonce()
  45. hash = HashBytes(data.Bytes())
  46. }
  47. return data.GetNonce(), nil
  48. }
  49. func Uint64ToBytes(u uint64) []byte {
  50. buff := new(bytes.Buffer)
  51. err := binary.Write(buff, binary.LittleEndian, u)
  52. if err != nil {
  53. panic(err)
  54. }
  55. return buff.Bytes()
  56. }
  57. func Uint64FromBytes(b []byte) uint64 {
  58. return binary.LittleEndian.Uint64(b)
  59. }