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