github.com/klaytn/klaytn@v1.10.2/common/types.go (about)

     1  // Modifications Copyright 2018 The klaytn Authors
     2  // Copyright 2015 The go-ethereum Authors
     3  // This file is part of the go-ethereum library.
     4  //
     5  // The go-ethereum library is free software: you can redistribute it and/or modify
     6  // it under the terms of the GNU Lesser General Public License as published by
     7  // the Free Software Foundation, either version 3 of the License, or
     8  // (at your option) any later version.
     9  //
    10  // The go-ethereum library is distributed in the hope that it will be useful,
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    13  // GNU Lesser General Public License for more details.
    14  //
    15  // You should have received a copy of the GNU Lesser General Public License
    16  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    17  //
    18  // This file is derived from common/types.go (2018/06/04).
    19  // Modified and improved for the klaytn development.
    20  
    21  package common
    22  
    23  import (
    24  	"bytes"
    25  	"encoding/hex"
    26  	"errors"
    27  	"fmt"
    28  	"math/big"
    29  	"math/rand"
    30  	"reflect"
    31  
    32  	"github.com/klaytn/klaytn/common/hexutil"
    33  	"github.com/klaytn/klaytn/crypto/sha3"
    34  )
    35  
    36  const (
    37  	HashLength      = 32
    38  	AddressLength   = 20
    39  	SignatureLength = 65
    40  )
    41  
    42  var (
    43  	hashT    = reflect.TypeOf(Hash{})
    44  	addressT = reflect.TypeOf(Address{})
    45  )
    46  
    47  var lastPrecompiledContractAddressHex = hexutil.MustDecode("0x00000000000000000000000000000000000003FF")
    48  
    49  var (
    50  	errStringLengthExceedsAddressLength = errors.New("the string length exceeds the address length (20)")
    51  	errEmptyString                      = errors.New("empty string")
    52  )
    53  
    54  // Hash represents the 32 byte Keccak256 hash of arbitrary data.
    55  type Hash [HashLength]byte
    56  
    57  // BytesToHash sets b to hash.
    58  // If b is larger than len(h), b will be cropped from the left.
    59  func BytesToHash(b []byte) Hash {
    60  	var h Hash
    61  	h.SetBytes(b)
    62  	return h
    63  }
    64  
    65  // BigToHash sets byte representation of b to hash.
    66  // If b is larger than len(h), b will be cropped from the left.
    67  func BigToHash(b *big.Int) Hash { return BytesToHash(b.Bytes()) }
    68  
    69  // HexToHash sets byte representation of s to hash.
    70  // If b is larger than len(h), b will be cropped from the left.
    71  func HexToHash(s string) Hash { return BytesToHash(FromHex(s)) }
    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, forcing the byte slice to be formatted as is,
    95  // without going through the stringer interface used for logging.
    96  func (h Hash) Format(s fmt.State, c rune) {
    97  	fmt.Fprintf(s, "%"+string(c), h[:])
    98  }
    99  
   100  // UnmarshalText parses a hash in hex syntax.
   101  func (h *Hash) UnmarshalText(input []byte) error {
   102  	return hexutil.UnmarshalFixedText("Hash", input, h[:])
   103  }
   104  
   105  // UnmarshalJSON parses a hash in hex syntax.
   106  func (h *Hash) UnmarshalJSON(input []byte) error {
   107  	return hexutil.UnmarshalFixedJSON(hashT, input, h[:])
   108  }
   109  
   110  // MarshalText returns the hex representation of h.
   111  func (h Hash) MarshalText() ([]byte, error) {
   112  	return hexutil.Bytes(h[:]).MarshalText()
   113  }
   114  
   115  // SetBytes sets the hash to the value of b.
   116  // If b is larger than len(h), b will be cropped from the left.
   117  func (h *Hash) SetBytes(b []byte) {
   118  	if len(b) > len(h) {
   119  		b = b[len(b)-HashLength:]
   120  	}
   121  
   122  	copy(h[HashLength-len(b):], b)
   123  }
   124  
   125  // Generate implements testing/quick.Generator.
   126  func (h Hash) Generate(rand *rand.Rand, size int) reflect.Value {
   127  	m := rand.Intn(len(h))
   128  	for i := len(h) - 1; i > m; i-- {
   129  		h[i] = byte(rand.Uint32())
   130  	}
   131  	return reflect.ValueOf(h)
   132  }
   133  
   134  // getShardIndex returns the index of the shard.
   135  // The address is arranged in the front or back of the array according to the initialization method.
   136  // And the opposite is zero. In any case, to calculate the various shard index values,
   137  // add both values and shift to calculate the shard index.
   138  func (h Hash) getShardIndex(shardMask int) int {
   139  	data1 := int(h[HashLength-1]) + int(h[0])
   140  	data2 := int(h[HashLength-2]) + int(h[1])
   141  	return ((data2 << 8) + data1) & shardMask
   142  }
   143  
   144  func EmptyHash(h Hash) bool {
   145  	return h == Hash{}
   146  }
   147  
   148  // UnprefixedHash allows marshaling a Hash without 0x prefix.
   149  type UnprefixedHash Hash
   150  
   151  // UnmarshalText decodes the hash from hex. The 0x prefix is optional.
   152  func (h *UnprefixedHash) UnmarshalText(input []byte) error {
   153  	return hexutil.UnmarshalFixedUnprefixedText("UnprefixedHash", input, h[:])
   154  }
   155  
   156  // MarshalText encodes the hash as hex.
   157  func (h UnprefixedHash) MarshalText() ([]byte, error) {
   158  	return []byte(hex.EncodeToString(h[:])), nil
   159  }
   160  
   161  /////////// Address
   162  
   163  // Address represents the 20 byte address of a Klaytn account.
   164  type Address [AddressLength]byte
   165  
   166  func EmptyAddress(a Address) bool {
   167  	return a == Address{}
   168  }
   169  
   170  // BytesToAddress returns Address with value b.
   171  // If b is larger than len(h), b will be cropped from the left.
   172  func BytesToAddress(b []byte) Address {
   173  	var a Address
   174  	a.SetBytes(b)
   175  	return a
   176  }
   177  func StringToAddress(s string) Address { return BytesToAddress([]byte(s)) }
   178  
   179  // BigToAddress returns Address with byte values of b.
   180  // If b is larger than len(h), b will be cropped from the left.
   181  func BigToAddress(b *big.Int) Address { return BytesToAddress(b.Bytes()) }
   182  
   183  // HexToAddress returns Address with byte values of s.
   184  // If s is larger than len(h), s will be cropped from the left.
   185  func HexToAddress(s string) Address { return BytesToAddress(FromHex(s)) }
   186  
   187  // IsPrecompiledContractAddress returns true if the input address is in the range of precompiled contract addresses.
   188  func IsPrecompiledContractAddress(addr Address) bool {
   189  	if bytes.Compare(addr.Bytes(), lastPrecompiledContractAddressHex) > 0 || addr == (Address{}) {
   190  		return false
   191  	}
   192  	return true
   193  }
   194  
   195  // IsHexAddress verifies whether a string can represent a valid hex-encoded
   196  // Klaytn address or not.
   197  func IsHexAddress(s string) bool {
   198  	if hasHexPrefix(s) {
   199  		s = s[2:]
   200  	}
   201  	return len(s) == 2*AddressLength && isHex(s)
   202  }
   203  
   204  // Bytes gets the string representation of the underlying address.
   205  func (a Address) Bytes() []byte { return a[:] }
   206  
   207  // Hash converts an address to a hash by left-padding it with zeros.
   208  func (a Address) Hash() Hash { return BytesToHash(a[:]) }
   209  
   210  // Hex returns an EIP55-compliant hex string representation of the address.
   211  func (a Address) Hex() string {
   212  	unchecksummed := hex.EncodeToString(a[:])
   213  	sha := sha3.NewKeccak256()
   214  	sha.Write([]byte(unchecksummed))
   215  	hash := sha.Sum(nil)
   216  
   217  	result := []byte(unchecksummed)
   218  	for i := 0; i < len(result); i++ {
   219  		hashByte := hash[i/2]
   220  		if i%2 == 0 {
   221  			hashByte = hashByte >> 4
   222  		} else {
   223  			hashByte &= 0xf
   224  		}
   225  		if result[i] > '9' && hashByte > 7 {
   226  			result[i] -= 32
   227  		}
   228  	}
   229  	return "0x" + string(result)
   230  }
   231  
   232  // String implements fmt.Stringer.
   233  func (a Address) String() string {
   234  	return a.Hex()
   235  }
   236  
   237  // Format implements fmt.Formatter, forcing the byte slice to be formatted as is,
   238  // without going through the stringer interface used for logging.
   239  func (a Address) Format(s fmt.State, c rune) {
   240  	fmt.Fprintf(s, "%"+string(c), a[:])
   241  }
   242  
   243  // SetBytes sets the address to the value of b.
   244  // If b is larger than len(a) it will panic.
   245  func (a *Address) SetBytes(b []byte) {
   246  	if len(b) > len(a) {
   247  		b = b[len(b)-AddressLength:]
   248  	}
   249  	copy(a[AddressLength-len(b):], b)
   250  }
   251  
   252  // SetBytesFromFront sets the address to the value of b.
   253  // If len(b) is larger, take AddressLength bytes from front.
   254  func (a *Address) SetBytesFromFront(b []byte) {
   255  	if len(b) > AddressLength {
   256  		b = b[:AddressLength]
   257  	}
   258  	copy(a[:], b)
   259  }
   260  
   261  // MarshalText returns the hex representation of a.
   262  func (a Address) MarshalText() ([]byte, error) {
   263  	return hexutil.Bytes(a[:]).MarshalText()
   264  }
   265  
   266  // UnmarshalText parses a hash in hex syntax.
   267  func (a *Address) UnmarshalText(input []byte) error {
   268  	return hexutil.UnmarshalFixedText("Address", input, a[:])
   269  }
   270  
   271  // UnmarshalJSON parses a hash in hex syntax.
   272  func (a *Address) UnmarshalJSON(input []byte) error {
   273  	return hexutil.UnmarshalFixedJSON(addressT, input, a[:])
   274  }
   275  
   276  // getShardIndex returns the index of the shard.
   277  // The address is arranged in the front or back of the array according to the initialization method.
   278  // And the opposite is zero. In any case, to calculate the various shard index values,
   279  // add both values and shift to calculate the shard index.
   280  func (a Address) getShardIndex(shardMask int) int {
   281  	data1 := int(a[AddressLength-1]) + int(a[0])
   282  	data2 := int(a[AddressLength-2]) + int(a[1])
   283  	return ((data2 << 8) + data1) & shardMask
   284  }
   285  
   286  // UnprefixedAddress allows marshaling an Address without 0x prefix.
   287  type UnprefixedAddress Address
   288  
   289  // UnmarshalText decodes the address from hex. The 0x prefix is optional.
   290  func (a *UnprefixedAddress) UnmarshalText(input []byte) error {
   291  	return hexutil.UnmarshalFixedUnprefixedText("UnprefixedAddress", input, a[:])
   292  }
   293  
   294  // MarshalText encodes the address as hex.
   295  func (a UnprefixedAddress) MarshalText() ([]byte, error) {
   296  	return []byte(hex.EncodeToString(a[:])), nil
   297  }
   298  
   299  type ConnType int
   300  
   301  const ConnTypeUndefined ConnType = -1
   302  
   303  const (
   304  	CONSENSUSNODE ConnType = iota
   305  	ENDPOINTNODE
   306  	PROXYNODE
   307  	BOOTNODE
   308  	UNKNOWNNODE // For error case
   309  )
   310  
   311  func (ct ConnType) Valid() bool {
   312  	if int(ct) > 255 {
   313  		return false
   314  	}
   315  	return true
   316  }
   317  
   318  func (ct ConnType) String() string {
   319  	s := fmt.Sprintf("%d", int(ct))
   320  	return s
   321  }