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

package core
import (
"bytes"
"crypto/sha256"
"encoding/binary"
"encoding/hex"
)
// Hash is the type for a hash data packet
type Hash [32]byte
// IsZero returns true if the Hash is empty (all zeroes)
func (h *Hash) IsZero() bool {
z := Hash{}
if bytes.Equal(z[:], h[:]) {
return true
}
return false
}
func (h *Hash) String() string {
return hex.EncodeToString(h[:])
}
// HashBytes performs a hash over a given byte array
func HashBytes(b []byte) Hash {
h := sha256.Sum256(b)
return h
}
// PoWData is the interface for the data that have the Nonce parameter to calculate the Proof-of-Work
type PoWData interface {
Bytes() []byte
GetNonce() uint64
IncrementNonce()
}
// CheckPoW verifies the PoW difficulty of a Hash
func CheckPoW(hash Hash, difficulty uint64) bool {
var empty [32]byte
if !bytes.Equal(hash[:][0:difficulty], empty[0:difficulty]) {
return false
}
return true
}
// CalculatePoW calculates the nonce for the given data in order to fit in the current Proof of Work difficulty
func CalculatePoW(data PoWData, difficulty uint64) (uint64, error) {
hash := HashBytes(data.Bytes())
for !CheckPoW(hash, difficulty) {
data.IncrementNonce()
hash = HashBytes(data.Bytes())
}
return data.GetNonce(), nil
}
func Uint64ToBytes(u uint64) []byte {
buff := new(bytes.Buffer)
err := binary.Write(buff, binary.LittleEndian, u)
if err != nil {
panic(err)
}
return buff.Bytes()
}
func Uint64FromBytes(b []byte) uint64 {
return binary.LittleEndian.Uint64(b)
}