github.com/neatlab/neatio@v1.7.3-0.20220425043230-d903e92fcc75/utilities/common/types.go (about)

     1  package common
     2  
     3  import (
     4  	"encoding/hex"
     5  	"fmt"
     6  	"math/big"
     7  	"math/rand"
     8  	"reflect"
     9  
    10  	"github.com/neatlab/neatio/utilities/common/hexutil"
    11  	"golang.org/x/crypto/sha3"
    12  )
    13  
    14  const (
    15  	HashLength    = 32
    16  	AddressLength = 20
    17  )
    18  
    19  var (
    20  	hashT    = reflect.TypeOf(Hash{})
    21  	addressT = reflect.TypeOf(Address{})
    22  )
    23  
    24  type Hash [HashLength]byte
    25  
    26  func BytesToHash(b []byte) Hash {
    27  	var h Hash
    28  	h.SetBytes(b)
    29  	return h
    30  }
    31  func StringToHash(s string) Hash { return BytesToHash([]byte(s)) }
    32  func BigToHash(b *big.Int) Hash  { return BytesToHash(b.Bytes()) }
    33  func HexToHash(s string) Hash    { return BytesToHash(FromHex(s)) }
    34  
    35  func (h Hash) Str() string   { return string(h[:]) }
    36  func (h Hash) Bytes() []byte { return h[:] }
    37  func (h Hash) Big() *big.Int { return new(big.Int).SetBytes(h[:]) }
    38  func (h Hash) Hex() string   { return hexutil.Encode(h[:]) }
    39  
    40  func (h Hash) TerminalString() string {
    41  	return fmt.Sprintf("%x…%x", h[:3], h[29:])
    42  }
    43  
    44  func (h Hash) String() string {
    45  	return h.Hex()
    46  }
    47  
    48  func (h Hash) Format(s fmt.State, c rune) {
    49  	fmt.Fprintf(s, "%"+string(c), h[:])
    50  }
    51  
    52  func (h *Hash) UnmarshalText(input []byte) error {
    53  	return hexutil.UnmarshalFixedText("Hash", input, h[:])
    54  }
    55  
    56  func (h *Hash) UnmarshalJSON(input []byte) error {
    57  	return hexutil.UnmarshalFixedJSON(hashT, input, h[:])
    58  }
    59  
    60  func (h Hash) MarshalText() ([]byte, error) {
    61  	return hexutil.Bytes(h[:]).MarshalText()
    62  }
    63  
    64  func (h *Hash) SetBytes(b []byte) {
    65  	if len(b) > len(h) {
    66  		b = b[len(b)-HashLength:]
    67  	}
    68  
    69  	copy(h[HashLength-len(b):], b)
    70  }
    71  
    72  func (h *Hash) SetString(s string) { h.SetBytes([]byte(s)) }
    73  
    74  func (h *Hash) Set(other Hash) {
    75  	for i, v := range other {
    76  		h[i] = v
    77  	}
    78  }
    79  
    80  func (h Hash) Generate(rand *rand.Rand, size int) reflect.Value {
    81  	m := rand.Intn(len(h))
    82  	for i := len(h) - 1; i > m; i-- {
    83  		h[i] = byte(rand.Uint32())
    84  	}
    85  	return reflect.ValueOf(h)
    86  }
    87  
    88  func EmptyHash(h Hash) bool {
    89  	return h == Hash{}
    90  }
    91  
    92  type UnprefixedHash Hash
    93  
    94  func (h *UnprefixedHash) UnmarshalText(input []byte) error {
    95  	return hexutil.UnmarshalFixedUnprefixedText("UnprefixedHash", input, h[:])
    96  }
    97  
    98  func (h UnprefixedHash) MarshalText() ([]byte, error) {
    99  	return []byte(hex.EncodeToString(h[:])), nil
   100  }
   101  
   102  type Address [AddressLength]byte
   103  
   104  func BytesToAddress(b []byte) Address {
   105  	var a Address
   106  	a.SetBytes(b)
   107  	return a
   108  }
   109  func StringToAddress(s string) Address { return BytesToAddress([]byte(s)) }
   110  func BigToAddress(b *big.Int) Address  { return BytesToAddress(b.Bytes()) }
   111  func HexToAddress(s string) Address    { return BytesToAddress(FromHex(s)) }
   112  
   113  func IsHexAddress(s string) bool {
   114  	if hasHexPrefix(s) {
   115  		s = s[2:]
   116  	}
   117  	return len(s) == 2*AddressLength && isHex(s)
   118  }
   119  
   120  func (a Address) Str() string   { return string(a[:]) }
   121  func (a Address) Bytes() []byte { return a[:] }
   122  func (a Address) Big() *big.Int { return new(big.Int).SetBytes(a[:]) }
   123  func (a Address) Hash() Hash    { return BytesToHash(a[:]) }
   124  
   125  func (a Address) Hex() string {
   126  	unchecksummed := hex.EncodeToString(a[:])
   127  	sha := sha3.NewLegacyKeccak256()
   128  	sha.Write([]byte(unchecksummed))
   129  	hash := sha.Sum(nil)
   130  
   131  	result := []byte(unchecksummed)
   132  	for i := 0; i < len(result); i++ {
   133  		hashByte := hash[i/2]
   134  		if i%2 == 0 {
   135  			hashByte = hashByte >> 4
   136  		} else {
   137  			hashByte &= 0xf
   138  		}
   139  		if result[i] > '9' && hashByte > 7 {
   140  			result[i] -= 32
   141  		}
   142  	}
   143  	return "0x" + string(result)
   144  }
   145  
   146  func (a Address) String() string {
   147  	return a.Hex()
   148  }
   149  
   150  func (a Address) Format(s fmt.State, c rune) {
   151  	fmt.Fprintf(s, "%"+string(c), a[:])
   152  }
   153  
   154  func (a *Address) SetBytes(b []byte) {
   155  	if len(b) > len(a) {
   156  		b = b[len(b)-AddressLength:]
   157  	}
   158  	copy(a[AddressLength-len(b):], b)
   159  }
   160  
   161  func (a *Address) SetString(s string) { a.SetBytes([]byte(s)) }
   162  
   163  func (a *Address) Set(other Address) {
   164  	for i, v := range other {
   165  		a[i] = v
   166  	}
   167  }
   168  
   169  func (a Address) MarshalText() ([]byte, error) {
   170  	return hexutil.Bytes(a[:]).MarshalText()
   171  }
   172  
   173  func (a *Address) UnmarshalText(input []byte) error {
   174  	return hexutil.UnmarshalFixedText("Address", input, a[:])
   175  }
   176  
   177  func (a *Address) UnmarshalJSON(input []byte) error {
   178  	return hexutil.UnmarshalFixedJSON(addressT, input, a[:])
   179  }
   180  
   181  type UnprefixedAddress Address
   182  
   183  func (a *UnprefixedAddress) UnmarshalText(input []byte) error {
   184  	return hexutil.UnmarshalFixedUnprefixedText("UnprefixedAddress", input, a[:])
   185  }
   186  
   187  func (a UnprefixedAddress) MarshalText() ([]byte, error) {
   188  	return []byte(hex.EncodeToString(a[:])), nil
   189  }