github.com/theQRL/go-zond@v0.1.1/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  	"bytes"
    21  	"database/sql/driver"
    22  	"encoding/hex"
    23  	"encoding/json"
    24  	"errors"
    25  	"fmt"
    26  	"math/big"
    27  	"math/rand"
    28  	"reflect"
    29  	"strconv"
    30  	"strings"
    31  
    32  	"github.com/theQRL/go-zond/common/hexutil"
    33  	"golang.org/x/crypto/sha3"
    34  )
    35  
    36  // Lengths of hashes and addresses in bytes.
    37  const (
    38  	// HashLength is the expected length of the hash
    39  	HashLength = 32
    40  	// AddressLength is the expected length of the address
    41  	AddressLength = 20
    42  )
    43  
    44  var (
    45  	hashT    = reflect.TypeOf(Hash{})
    46  	addressT = reflect.TypeOf(Address{})
    47  )
    48  
    49  // Hash represents the 32 byte Keccak256 hash of arbitrary data.
    50  type Hash [HashLength]byte
    51  
    52  // BytesToHash sets b to hash.
    53  // If b is larger than len(h), b will be cropped from the left.
    54  func BytesToHash(b []byte) Hash {
    55  	var h Hash
    56  	h.SetBytes(b)
    57  	return h
    58  }
    59  
    60  // BigToHash sets byte representation of b to hash.
    61  // If b is larger than len(h), b will be cropped from the left.
    62  func BigToHash(b *big.Int) Hash { return BytesToHash(b.Bytes()) }
    63  
    64  // HexToHash sets byte representation of s to hash.
    65  // If b is larger than len(h), b will be cropped from the left.
    66  func HexToHash(s string) Hash { return BytesToHash(FromHex(s)) }
    67  
    68  // Cmp compares two hashes.
    69  func (h Hash) Cmp(other Hash) int {
    70  	return bytes.Compare(h[:], other[:])
    71  }
    72  
    73  // Bytes gets the byte representation of the underlying hash.
    74  func (h Hash) Bytes() []byte { return h[:] }
    75  
    76  // Big converts a hash to a big integer.
    77  func (h Hash) Big() *big.Int { return new(big.Int).SetBytes(h[:]) }
    78  
    79  // Hex converts a hash to a hex string.
    80  func (h Hash) Hex() string { return hexutil.Encode(h[:]) }
    81  
    82  // TerminalString implements log.TerminalStringer, formatting a string for console
    83  // output during logging.
    84  func (h Hash) TerminalString() string {
    85  	return fmt.Sprintf("%x..%x", h[:3], h[29:])
    86  }
    87  
    88  // String implements the stringer interface and is used also by the logger when
    89  // doing full logging into a file.
    90  func (h Hash) String() string {
    91  	return h.Hex()
    92  }
    93  
    94  // Format implements fmt.Formatter.
    95  // Hash supports the %v, %s, %q, %x, %X and %d format verbs.
    96  func (h Hash) Format(s fmt.State, c rune) {
    97  	hexb := make([]byte, 2+len(h)*2)
    98  	copy(hexb, "0x")
    99  	hex.Encode(hexb[2:], h[:])
   100  
   101  	switch c {
   102  	case 'x', 'X':
   103  		if !s.Flag('#') {
   104  			hexb = hexb[2:]
   105  		}
   106  		if c == 'X' {
   107  			hexb = bytes.ToUpper(hexb)
   108  		}
   109  		fallthrough
   110  	case 'v', 's':
   111  		s.Write(hexb)
   112  	case 'q':
   113  		q := []byte{'"'}
   114  		s.Write(q)
   115  		s.Write(hexb)
   116  		s.Write(q)
   117  	case 'd':
   118  		fmt.Fprint(s, ([len(h)]byte)(h))
   119  	default:
   120  		fmt.Fprintf(s, "%%!%c(hash=%x)", c, h)
   121  	}
   122  }
   123  
   124  // UnmarshalText parses a hash in hex syntax.
   125  func (h *Hash) UnmarshalText(input []byte) error {
   126  	return hexutil.UnmarshalFixedText("Hash", input, h[:])
   127  }
   128  
   129  // UnmarshalJSON parses a hash in hex syntax.
   130  func (h *Hash) UnmarshalJSON(input []byte) error {
   131  	return hexutil.UnmarshalFixedJSON(hashT, input, h[:])
   132  }
   133  
   134  // MarshalText returns the hex representation of h.
   135  func (h Hash) MarshalText() ([]byte, error) {
   136  	return hexutil.Bytes(h[:]).MarshalText()
   137  }
   138  
   139  // SetBytes sets the hash to the value of b.
   140  // If b is larger than len(h), b will be cropped from the left.
   141  func (h *Hash) SetBytes(b []byte) {
   142  	if len(b) > len(h) {
   143  		b = b[len(b)-HashLength:]
   144  	}
   145  
   146  	copy(h[HashLength-len(b):], b)
   147  }
   148  
   149  // Generate implements testing/quick.Generator.
   150  func (h Hash) Generate(rand *rand.Rand, size int) reflect.Value {
   151  	m := rand.Intn(len(h))
   152  	for i := len(h) - 1; i > m; i-- {
   153  		h[i] = byte(rand.Uint32())
   154  	}
   155  	return reflect.ValueOf(h)
   156  }
   157  
   158  // Scan implements Scanner for database/sql.
   159  func (h *Hash) Scan(src interface{}) error {
   160  	srcB, ok := src.([]byte)
   161  	if !ok {
   162  		return fmt.Errorf("can't scan %T into Hash", src)
   163  	}
   164  	if len(srcB) != HashLength {
   165  		return fmt.Errorf("can't scan []byte of len %d into Hash, want %d", len(srcB), HashLength)
   166  	}
   167  	copy(h[:], srcB)
   168  	return nil
   169  }
   170  
   171  // Value implements valuer for database/sql.
   172  func (h Hash) Value() (driver.Value, error) {
   173  	return h[:], nil
   174  }
   175  
   176  // ImplementsGraphQLType returns true if Hash implements the specified GraphQL type.
   177  func (Hash) ImplementsGraphQLType(name string) bool { return name == "Bytes32" }
   178  
   179  // UnmarshalGraphQL unmarshals the provided GraphQL query data.
   180  func (h *Hash) UnmarshalGraphQL(input interface{}) error {
   181  	var err error
   182  	switch input := input.(type) {
   183  	case string:
   184  		err = h.UnmarshalText([]byte(input))
   185  	default:
   186  		err = fmt.Errorf("unexpected type %T for Hash", input)
   187  	}
   188  	return err
   189  }
   190  
   191  // UnprefixedHash allows marshaling a Hash without 0x prefix.
   192  type UnprefixedHash Hash
   193  
   194  // UnmarshalText decodes the hash from hex. The 0x prefix is optional.
   195  func (h *UnprefixedHash) UnmarshalText(input []byte) error {
   196  	return hexutil.UnmarshalFixedUnprefixedText("UnprefixedHash", input, h[:])
   197  }
   198  
   199  // MarshalText encodes the hash as hex.
   200  func (h UnprefixedHash) MarshalText() ([]byte, error) {
   201  	return []byte(hex.EncodeToString(h[:])), nil
   202  }
   203  
   204  /////////// Address
   205  
   206  // Address represents the 20 byte address of an Ethereum account.
   207  type Address [AddressLength]byte
   208  
   209  // BytesToAddress returns Address with value b.
   210  // If b is larger than len(h), b will be cropped from the left.
   211  func BytesToAddress(b []byte) Address {
   212  	var a Address
   213  	a.SetBytes(b)
   214  	return a
   215  }
   216  
   217  // BigToAddress returns Address with byte values of b.
   218  // If b is larger than len(h), b will be cropped from the left.
   219  func BigToAddress(b *big.Int) Address { return BytesToAddress(b.Bytes()) }
   220  
   221  // HexToAddress returns Address with byte values of s.
   222  // If s is larger than len(h), s will be cropped from the left.
   223  func HexToAddress(s string) Address { return BytesToAddress(FromHex(s)) }
   224  
   225  // IsHexAddress verifies whether a string can represent a valid hex-encoded
   226  // Ethereum address or not.
   227  func IsHexAddress(s string) bool {
   228  	if has0xPrefix(s) {
   229  		s = s[2:]
   230  	}
   231  	return len(s) == 2*AddressLength && isHex(s)
   232  }
   233  
   234  // Cmp compares two addresses.
   235  func (a Address) Cmp(other Address) int {
   236  	return bytes.Compare(a[:], other[:])
   237  }
   238  
   239  // Bytes gets the string representation of the underlying address.
   240  func (a Address) Bytes() []byte { return a[:] }
   241  
   242  // Hash converts an address to a hash by left-padding it with zeros.
   243  func (a Address) Hash() Hash { return BytesToHash(a[:]) }
   244  
   245  // Big converts an address to a big integer.
   246  func (a Address) Big() *big.Int { return new(big.Int).SetBytes(a[:]) }
   247  
   248  // Hex returns an EIP55-compliant hex string representation of the address.
   249  func (a Address) Hex() string {
   250  	return string(a.checksumHex())
   251  }
   252  
   253  // String implements fmt.Stringer.
   254  func (a Address) String() string {
   255  	return a.Hex()
   256  }
   257  
   258  func (a *Address) checksumHex() []byte {
   259  	buf := a.hex()
   260  
   261  	// compute checksum
   262  	sha := sha3.NewLegacyKeccak256()
   263  	sha.Write(buf[2:])
   264  	hash := sha.Sum(nil)
   265  	for i := 2; i < len(buf); i++ {
   266  		hashByte := hash[(i-2)/2]
   267  		if i%2 == 0 {
   268  			hashByte = hashByte >> 4
   269  		} else {
   270  			hashByte &= 0xf
   271  		}
   272  		if buf[i] > '9' && hashByte > 7 {
   273  			buf[i] -= 32
   274  		}
   275  	}
   276  	return buf[:]
   277  }
   278  
   279  func (a Address) hex() []byte {
   280  	var buf [len(a)*2 + 2]byte
   281  	copy(buf[:2], "0x")
   282  	hex.Encode(buf[2:], a[:])
   283  	return buf[:]
   284  }
   285  
   286  // Format implements fmt.Formatter.
   287  // Address supports the %v, %s, %q, %x, %X and %d format verbs.
   288  func (a Address) Format(s fmt.State, c rune) {
   289  	switch c {
   290  	case 'v', 's':
   291  		s.Write(a.checksumHex())
   292  	case 'q':
   293  		q := []byte{'"'}
   294  		s.Write(q)
   295  		s.Write(a.checksumHex())
   296  		s.Write(q)
   297  	case 'x', 'X':
   298  		// %x disables the checksum.
   299  		hex := a.hex()
   300  		if !s.Flag('#') {
   301  			hex = hex[2:]
   302  		}
   303  		if c == 'X' {
   304  			hex = bytes.ToUpper(hex)
   305  		}
   306  		s.Write(hex)
   307  	case 'd':
   308  		fmt.Fprint(s, ([len(a)]byte)(a))
   309  	default:
   310  		fmt.Fprintf(s, "%%!%c(address=%x)", c, a)
   311  	}
   312  }
   313  
   314  // SetBytes sets the address to the value of b.
   315  // If b is larger than len(a), b will be cropped from the left.
   316  func (a *Address) SetBytes(b []byte) {
   317  	if len(b) > len(a) {
   318  		b = b[len(b)-AddressLength:]
   319  	}
   320  	copy(a[AddressLength-len(b):], b)
   321  }
   322  
   323  // MarshalText returns the hex representation of a.
   324  func (a Address) MarshalText() ([]byte, error) {
   325  	return hexutil.Bytes(a[:]).MarshalText()
   326  }
   327  
   328  // UnmarshalText parses a hash in hex syntax.
   329  func (a *Address) UnmarshalText(input []byte) error {
   330  	return hexutil.UnmarshalFixedText("Address", input, a[:])
   331  }
   332  
   333  // UnmarshalJSON parses a hash in hex syntax.
   334  func (a *Address) UnmarshalJSON(input []byte) error {
   335  	return hexutil.UnmarshalFixedJSON(addressT, input, a[:])
   336  }
   337  
   338  // Scan implements Scanner for database/sql.
   339  func (a *Address) Scan(src interface{}) error {
   340  	srcB, ok := src.([]byte)
   341  	if !ok {
   342  		return fmt.Errorf("can't scan %T into Address", src)
   343  	}
   344  	if len(srcB) != AddressLength {
   345  		return fmt.Errorf("can't scan []byte of len %d into Address, want %d", len(srcB), AddressLength)
   346  	}
   347  	copy(a[:], srcB)
   348  	return nil
   349  }
   350  
   351  // Value implements valuer for database/sql.
   352  func (a Address) Value() (driver.Value, error) {
   353  	return a[:], nil
   354  }
   355  
   356  // ImplementsGraphQLType returns true if Hash implements the specified GraphQL type.
   357  func (a Address) ImplementsGraphQLType(name string) bool { return name == "Address" }
   358  
   359  // UnmarshalGraphQL unmarshals the provided GraphQL query data.
   360  func (a *Address) UnmarshalGraphQL(input interface{}) error {
   361  	var err error
   362  	switch input := input.(type) {
   363  	case string:
   364  		err = a.UnmarshalText([]byte(input))
   365  	default:
   366  		err = fmt.Errorf("unexpected type %T for Address", input)
   367  	}
   368  	return err
   369  }
   370  
   371  // UnprefixedAddress allows marshaling an Address without 0x prefix.
   372  type UnprefixedAddress Address
   373  
   374  // UnmarshalText decodes the address from hex. The 0x prefix is optional.
   375  func (a *UnprefixedAddress) UnmarshalText(input []byte) error {
   376  	return hexutil.UnmarshalFixedUnprefixedText("UnprefixedAddress", input, a[:])
   377  }
   378  
   379  // MarshalText encodes the address as hex.
   380  func (a UnprefixedAddress) MarshalText() ([]byte, error) {
   381  	return []byte(hex.EncodeToString(a[:])), nil
   382  }
   383  
   384  // MixedcaseAddress retains the original string, which may or may not be
   385  // correctly checksummed
   386  type MixedcaseAddress struct {
   387  	addr     Address
   388  	original string
   389  }
   390  
   391  // NewMixedcaseAddress constructor (mainly for testing)
   392  func NewMixedcaseAddress(addr Address) MixedcaseAddress {
   393  	return MixedcaseAddress{addr: addr, original: addr.Hex()}
   394  }
   395  
   396  // NewMixedcaseAddressFromString is mainly meant for unit-testing
   397  func NewMixedcaseAddressFromString(hexaddr string) (*MixedcaseAddress, error) {
   398  	if !IsHexAddress(hexaddr) {
   399  		return nil, errors.New("invalid address")
   400  	}
   401  	a := FromHex(hexaddr)
   402  	return &MixedcaseAddress{addr: BytesToAddress(a), original: hexaddr}, nil
   403  }
   404  
   405  // UnmarshalJSON parses MixedcaseAddress
   406  func (ma *MixedcaseAddress) UnmarshalJSON(input []byte) error {
   407  	if err := hexutil.UnmarshalFixedJSON(addressT, input, ma.addr[:]); err != nil {
   408  		return err
   409  	}
   410  	return json.Unmarshal(input, &ma.original)
   411  }
   412  
   413  // MarshalJSON marshals the original value
   414  func (ma MixedcaseAddress) MarshalJSON() ([]byte, error) {
   415  	if strings.HasPrefix(ma.original, "0x") || strings.HasPrefix(ma.original, "0X") {
   416  		return json.Marshal(fmt.Sprintf("0x%s", ma.original[2:]))
   417  	}
   418  	return json.Marshal(fmt.Sprintf("0x%s", ma.original))
   419  }
   420  
   421  // Address returns the address
   422  func (ma *MixedcaseAddress) Address() Address {
   423  	return ma.addr
   424  }
   425  
   426  // String implements fmt.Stringer
   427  func (ma *MixedcaseAddress) String() string {
   428  	if ma.ValidChecksum() {
   429  		return fmt.Sprintf("%s [chksum ok]", ma.original)
   430  	}
   431  	return fmt.Sprintf("%s [chksum INVALID]", ma.original)
   432  }
   433  
   434  // ValidChecksum returns true if the address has valid checksum
   435  func (ma *MixedcaseAddress) ValidChecksum() bool {
   436  	return ma.original == ma.addr.Hex()
   437  }
   438  
   439  // Original returns the mixed-case input string
   440  func (ma *MixedcaseAddress) Original() string {
   441  	return ma.original
   442  }
   443  
   444  // AddressEIP55 is an alias of Address with a customized json marshaller
   445  type AddressEIP55 Address
   446  
   447  // String returns the hex representation of the address in the manner of EIP55.
   448  func (addr AddressEIP55) String() string {
   449  	return Address(addr).Hex()
   450  }
   451  
   452  // MarshalJSON marshals the address in the manner of EIP55.
   453  func (addr AddressEIP55) MarshalJSON() ([]byte, error) {
   454  	return json.Marshal(addr.String())
   455  }
   456  
   457  type Decimal uint64
   458  
   459  func isString(input []byte) bool {
   460  	return len(input) >= 2 && input[0] == '"' && input[len(input)-1] == '"'
   461  }
   462  
   463  // UnmarshalJSON parses a hash in hex syntax.
   464  func (d *Decimal) UnmarshalJSON(input []byte) error {
   465  	if !isString(input) {
   466  		return &json.UnmarshalTypeError{Value: "non-string", Type: reflect.TypeOf(uint64(0))}
   467  	}
   468  	if i, err := strconv.ParseInt(string(input[1:len(input)-1]), 10, 64); err == nil {
   469  		*d = Decimal(i)
   470  		return nil
   471  	} else {
   472  		return err
   473  	}
   474  }