github.com/ethereumproject/go-ethereum@v5.5.2+incompatible/common/types.go (about)

     1  // Copyright 2015 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package common
    18  
    19  import (
    20  	"encoding/hex"
    21  	"encoding/json"
    22  	"errors"
    23  	"fmt"
    24  	"math/big"
    25  	"math/rand"
    26  	"reflect"
    27  	"strings"
    28  )
    29  
    30  const (
    31  	HashLength    = 32
    32  	AddressLength = 20
    33  )
    34  
    35  var hashJsonLengthErr = errors.New("common: unmarshalJSON failed: hash must be exactly 32 bytes")
    36  
    37  type (
    38  	Hash    [HashLength]byte
    39  	Address [AddressLength]byte
    40  )
    41  
    42  func BytesToHash(b []byte) Hash {
    43  	var h Hash
    44  	h.SetBytes(b)
    45  	return h
    46  }
    47  func BigToHash(b *big.Int) Hash { return BytesToHash(b.Bytes()) }
    48  func HexToHash(s string) Hash   { return BytesToHash(FromHex(s)) }
    49  
    50  // Don't use the default 'String' method in case we want to overwrite
    51  
    52  // Get the string representation of the underlying hash
    53  func (h Hash) Str() string   { return string(h[:]) }
    54  func (h Hash) Bytes() []byte { return h[:] }
    55  func (h Hash) Big() *big.Int { return new(big.Int).SetBytes(h[:]) }
    56  func (h Hash) Hex() string   { return "0x" + Bytes2Hex(h[:]) }
    57  
    58  // UnmarshalJSON parses a hash in its hex from to a hash.
    59  func (h *Hash) UnmarshalJSON(input []byte) error {
    60  	length := len(input)
    61  	if length >= 2 && input[0] == '"' && input[length-1] == '"' {
    62  		input = input[1 : length-1]
    63  	}
    64  	// strip "0x" for length check
    65  	if len(input) > 1 && strings.ToLower(string(input[:2])) == "0x" {
    66  		input = input[2:]
    67  	}
    68  
    69  	// validate the length of the input hash
    70  	if len(input) != HashLength*2 {
    71  		return hashJsonLengthErr
    72  	}
    73  	h.SetBytes(FromHex(string(input)))
    74  	return nil
    75  }
    76  
    77  // Serialize given hash to JSON
    78  func (h Hash) MarshalJSON() ([]byte, error) {
    79  	return json.Marshal(h.Hex())
    80  }
    81  
    82  // Sets the hash to the value of b. If b is larger than len(h) it will panic
    83  func (h *Hash) SetBytes(b []byte) {
    84  	if len(b) > len(h.Bytes()) {
    85  		b = b[len(b)-HashLength:]
    86  	}
    87  
    88  	copy(h[HashLength-len(b):], b)
    89  }
    90  
    91  // Set string `s` to h. If s is larger than len(h) it will panic
    92  func (h *Hash) SetString(s string) { h.SetBytes([]byte(s)) }
    93  
    94  // Sets h to other
    95  func (h *Hash) Set(other Hash) {
    96  	for i, v := range other {
    97  		h[i] = v
    98  	}
    99  }
   100  
   101  // Generate implements testing/quick.Generator.
   102  func (h Hash) Generate(rand *rand.Rand, size int) reflect.Value {
   103  	m := rand.Intn(len(h))
   104  	for i := len(h) - 1; i > m; i-- {
   105  		h[i] = byte(rand.Uint32())
   106  	}
   107  	return reflect.ValueOf(h)
   108  }
   109  
   110  func EmptyHash(h Hash) bool {
   111  	return h == Hash{}
   112  }
   113  
   114  func (h Hash) IsEmpty() bool {
   115  	return EmptyHash(h)
   116  }
   117  
   118  /////////// Address
   119  func BytesToAddress(b []byte) Address {
   120  	var a Address
   121  	a.SetBytes(b)
   122  	return a
   123  }
   124  func StringToAddress(s string) Address { return BytesToAddress([]byte(s)) }
   125  func BigToAddress(b *big.Int) Address  { return BytesToAddress(b.Bytes()) }
   126  func HexToAddress(s string) Address    { return BytesToAddress(FromHex(s)) }
   127  
   128  func EmptyAddress(a Address) bool {
   129  	return a == Address{}
   130  }
   131  
   132  func (a Address) IsEmpty() bool {
   133  	return EmptyAddress(a)
   134  }
   135  
   136  // IsHexAddress verifies whether a string can represent a valid hex-encoded
   137  // Ethereum address or not.
   138  func IsHexAddress(s string) bool {
   139  	if len(s) == 2+2*AddressLength && IsHex(s) {
   140  		return true
   141  	}
   142  	if len(s) == 2*AddressLength && IsHex("0x"+s) {
   143  		return true
   144  	}
   145  	return false
   146  }
   147  
   148  // Get the string representation of the underlying address
   149  func (a Address) Str() string   { return string(a[:]) }
   150  func (a Address) Bytes() []byte { return a[:] }
   151  func (a Address) Big() *big.Int { return new(big.Int).SetBytes(a[:]) }
   152  func (a Address) Hash() Hash    { return BytesToHash(a[:]) }
   153  func (a Address) Hex() string   { return "0x" + Bytes2Hex(a[:]) }
   154  
   155  // Sets the address to the value of b. If b is larger than len(a) it will panic
   156  func (a *Address) SetBytes(b []byte) {
   157  	if len(b) > len(a.Bytes()) {
   158  		b = b[len(b)-AddressLength:]
   159  	}
   160  	copy(a[AddressLength-len(b):], b)
   161  }
   162  
   163  // Set string `s` to a. If s is larger than len(a) it will panic
   164  func (a *Address) SetString(s string) { a.SetBytes([]byte(s)) }
   165  
   166  // Sets a to other
   167  func (a *Address) Set(other Address) {
   168  	for i, v := range other {
   169  		a[i] = v
   170  	}
   171  }
   172  
   173  // Serialize given address to JSON
   174  func (a Address) MarshalJSON() ([]byte, error) {
   175  	return json.Marshal(a.Hex())
   176  }
   177  
   178  // Parse address from raw json data
   179  func (a *Address) UnmarshalJSON(data []byte) error {
   180  	if len(data) > 2 && data[0] == '"' && data[len(data)-1] == '"' {
   181  		data = data[1 : len(data)-1]
   182  	}
   183  
   184  	if len(data) > 2 && data[0] == '0' && data[1] == 'x' {
   185  		data = data[2:]
   186  	}
   187  
   188  	if len(data) != 2*AddressLength {
   189  		return fmt.Errorf("Invalid address length, expected %d got %d bytes", 2*AddressLength, len(data))
   190  	}
   191  
   192  	n, err := hex.Decode(a[:], data)
   193  	if err != nil {
   194  		return err
   195  	}
   196  
   197  	if n != AddressLength {
   198  		return fmt.Errorf("Invalid address")
   199  	}
   200  
   201  	a.Set(HexToAddress(string(data)))
   202  	return nil
   203  }
   204  
   205  // PP Pretty Prints a byte slice in the following format:
   206  // 	hex(value[:4])...(hex[len(value)-4:])
   207  func PP(value []byte) string {
   208  	if len(value) <= 8 {
   209  		return Bytes2Hex(value)
   210  	}
   211  
   212  	return fmt.Sprintf("%x...%x", value[:4], value[len(value)-4])
   213  }