github.com/bytom/bytom@v1.1.2-0.20221014091027-bbcba3df6075/common/types.go (about)

     1  package common
     2  
     3  import (
     4  	_ "encoding/hex"
     5  	"encoding/json"
     6  	"errors"
     7  	"math/big"
     8  	"math/rand"
     9  	"reflect"
    10  	"strings"
    11  )
    12  
    13  const (
    14  	HashLength       = 32
    15  	AddressLength    = 42
    16  	PubkeyHashLength = 20
    17  )
    18  
    19  var hashJsonLengthErr = errors.New("common: unmarshalJSON failed: hash must be exactly 32 bytes")
    20  
    21  type (
    22  	Hash [HashLength]byte
    23  )
    24  
    25  func BytesToHash(b []byte) Hash {
    26  	var h Hash
    27  	h.SetBytes(b)
    28  	return h
    29  }
    30  
    31  func StringToHash(s string) Hash { return BytesToHash([]byte(s)) }
    32  func BigToHash(b *big.Int) Hash  { return BytesToHash(b.Bytes()) }
    33  
    34  // Don't use the default 'String' method in case we want to overwrite
    35  
    36  // Get the string representation of the underlying hash
    37  func (h Hash) Str() string   { return string(h[:]) }
    38  func (h Hash) Bytes() []byte { return h[:] }
    39  func (h Hash) Hex() string   { return "0x" + Bytes2Hex(h[:]) }
    40  
    41  // UnmarshalJSON parses a hash in its hex from to a hash.
    42  func (h *Hash) UnmarshalJSON(input []byte) error {
    43  	length := len(input)
    44  	if length >= 2 && input[0] == '"' && input[length-1] == '"' {
    45  		input = input[1 : length-1]
    46  	}
    47  	// strip "0x" for length check
    48  	if len(input) > 1 && strings.ToLower(string(input[:2])) == "0x" {
    49  		input = input[2:]
    50  	}
    51  
    52  	// validate the length of the input hash
    53  	if len(input) != HashLength*2 {
    54  		return hashJsonLengthErr
    55  	}
    56  	h.SetBytes(FromHex(string(input)))
    57  	return nil
    58  }
    59  
    60  // Serialize given hash to JSON
    61  func (h Hash) MarshalJSON() ([]byte, error) {
    62  	return json.Marshal(h.Hex())
    63  }
    64  
    65  // Sets the hash to the value of b. If b is larger than len(h) it will panic
    66  func (h *Hash) SetBytes(b []byte) {
    67  	if len(b) > len(h) {
    68  		b = b[len(b)-HashLength:]
    69  	}
    70  
    71  	copy(h[HashLength-len(b):], b)
    72  }
    73  
    74  // Sets h to other
    75  func (h *Hash) Set(other Hash) {
    76  	for i, v := range other {
    77  		h[i] = v
    78  	}
    79  }
    80  
    81  // Generate implements testing/quick.Generator.
    82  func (h Hash) Generate(rand *rand.Rand, size int) reflect.Value {
    83  	m := rand.Intn(len(h))
    84  	for i := len(h) - 1; i > m; i-- {
    85  		h[i] = byte(rand.Uint32())
    86  	}
    87  	return reflect.ValueOf(h)
    88  }
    89  
    90  func EmptyHash(h Hash) bool {
    91  	return h == Hash{}
    92  }