| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- import re
- from typing import (
- Any,
- Union,
- cast,
- )
- from eth_typing import (
- Address,
- AnyAddress,
- ChecksumAddress,
- HexAddress,
- HexStr,
- )
- from .conversions import (
- hexstr_if_str,
- to_hex,
- )
- from .crypto import (
- keccak,
- )
- from .hexadecimal import (
- add_0x_prefix,
- decode_hex,
- encode_hex,
- remove_0x_prefix,
- )
- from .types import (
- is_bytes,
- is_text,
- )
- _HEX_ADDRESS_REGEXP = re.compile("(0x)?[0-9a-f]{40}", re.IGNORECASE | re.ASCII)
- def is_hex_address(value: Any) -> bool:
- """
- Checks if the given string of text type is an address in hexadecimal encoded form.
- """
- if not is_text(value):
- return False
- return _HEX_ADDRESS_REGEXP.fullmatch(value) is not None
- def is_binary_address(value: Any) -> bool:
- """
- Checks if the given string is an address in raw bytes form.
- """
- if not is_bytes(value):
- return False
- elif len(value) != 20:
- return False
- else:
- return True
- def is_address(value: Any) -> bool:
- """
- Is the given string an address in any of the known formats?
- """
- if is_hex_address(value) or is_binary_address(value):
- return True
- return False
- def to_normalized_address(value: Union[AnyAddress, str, bytes]) -> HexAddress:
- """
- Converts an address to its normalized hexadecimal representation.
- """
- try:
- hex_address = hexstr_if_str(to_hex, value).lower()
- except AttributeError:
- raise TypeError(f"Value must be any string, instead got type {type(value)}")
- if is_address(hex_address):
- return HexAddress(HexStr(hex_address))
- else:
- raise ValueError(
- f"Unknown format {repr(value)}, attempted to normalize to "
- f"{repr(hex_address)}"
- )
- def is_normalized_address(value: Any) -> bool:
- """
- Returns whether the provided value is an address in its normalized form.
- """
- if not is_address(value):
- return False
- else:
- is_equal = value == to_normalized_address(value)
- return cast(bool, is_equal)
- def to_canonical_address(address: Union[AnyAddress, str, bytes]) -> Address:
- """
- Convert a valid address to its canonical form (20-length bytes).
- """
- return Address(decode_hex(to_normalized_address(address)))
- def is_canonical_address(address: Any) -> bool:
- """
- Returns `True` if the `value` is an address in its canonical form.
- """
- if not is_bytes(address) or len(address) != 20:
- return False
- is_equal = address == to_canonical_address(address)
- return cast(bool, is_equal)
- def is_same_address(
- left: Union[AnyAddress, str, bytes], right: Union[AnyAddress, str, bytes]
- ) -> bool:
- """
- Checks if both addresses are same or not.
- """
- if not is_address(left) or not is_address(right):
- raise ValueError("Both values must be valid addresses")
- else:
- return bool(to_normalized_address(left) == to_normalized_address(right))
- def to_checksum_address(value: Union[AnyAddress, str, bytes]) -> ChecksumAddress:
- """
- Makes a checksum address given a supported format.
- """
- norm_address = to_normalized_address(value)
- address_hash = encode_hex(keccak(text=remove_0x_prefix(HexStr(norm_address))))
- checksum_address = add_0x_prefix(
- HexStr(
- "".join(
- (
- norm_address[i].upper()
- if int(address_hash[i], 16) > 7
- else norm_address[i]
- )
- for i in range(2, 42)
- )
- )
- )
- return ChecksumAddress(HexAddress(checksum_address))
- def is_checksum_address(value: Any) -> bool:
- if not is_text(value):
- return False
- if not is_hex_address(value):
- return False
- is_equal = value == to_checksum_address(value)
- return cast(bool, is_equal)
- def _is_checksum_formatted(value: Any) -> bool:
- unprefixed_value = remove_0x_prefix(value)
- return (
- not unprefixed_value.islower()
- and not unprefixed_value.isupper()
- and not unprefixed_value.isnumeric()
- )
- def is_checksum_formatted_address(value: Any) -> bool:
- return is_hex_address(value) and _is_checksum_formatted(value)
|