add
This commit is contained in:
217
ccxt/static_dependencies/ethereum/abi/codec.py
Normal file
217
ccxt/static_dependencies/ethereum/abi/codec.py
Normal file
@@ -0,0 +1,217 @@
|
||||
from typing import (
|
||||
Any,
|
||||
Iterable,
|
||||
Tuple,
|
||||
)
|
||||
import warnings
|
||||
|
||||
from ..typing.abi import (
|
||||
Decodable,
|
||||
TypeStr,
|
||||
)
|
||||
from ..utils import (
|
||||
is_bytes,
|
||||
)
|
||||
|
||||
from .decoding import (
|
||||
ContextFramesBytesIO,
|
||||
TupleDecoder,
|
||||
)
|
||||
from .encoding import (
|
||||
TupleEncoder,
|
||||
)
|
||||
from .exceptions import (
|
||||
EncodingError,
|
||||
)
|
||||
from .registry import (
|
||||
ABIRegistry,
|
||||
)
|
||||
|
||||
|
||||
class BaseABICoder:
|
||||
"""
|
||||
Base class for porcelain coding APIs. These are classes which wrap
|
||||
instances of :class:`~.registry.ABIRegistry` to provide last-mile
|
||||
coding functionality.
|
||||
"""
|
||||
|
||||
def __init__(self, registry: ABIRegistry):
|
||||
"""
|
||||
Constructor.
|
||||
|
||||
:param registry: The registry providing the encoders to be used when
|
||||
encoding values.
|
||||
"""
|
||||
self._registry = registry
|
||||
|
||||
|
||||
class ABIEncoder(BaseABICoder):
|
||||
"""
|
||||
Wraps a registry to provide last-mile encoding functionality.
|
||||
"""
|
||||
|
||||
def encode_single(self, typ: TypeStr, arg: Any) -> bytes:
|
||||
"""
|
||||
Encodes the python value ``arg`` as a binary value of the ABI type
|
||||
``typ``.
|
||||
|
||||
:param typ: The string representation of the ABI type that will be used
|
||||
for encoding e.g. ``'uint256'``, ``'bytes[]'``, ``'(int,int)'``,
|
||||
etc.
|
||||
:param arg: The python value to be encoded.
|
||||
|
||||
:returns: The binary representation of the python value ``arg`` as a
|
||||
value of the ABI type ``typ``.
|
||||
"""
|
||||
warnings.warn(
|
||||
"abi.encode_single() and abi.encode_single_packed() are deprecated "
|
||||
"and will be removed in version 4.0.0 in favor of abi.encode() and "
|
||||
"abi.encode_packed(), respectively",
|
||||
category=DeprecationWarning,
|
||||
)
|
||||
|
||||
encoder = self._registry.get_encoder(typ)
|
||||
|
||||
return encoder(arg)
|
||||
|
||||
def encode_abi(self, types: Iterable[TypeStr], args: Iterable[Any]) -> bytes:
|
||||
"""
|
||||
Encodes the python values in ``args`` as a sequence of binary values of
|
||||
the ABI types in ``types`` via the head-tail mechanism.
|
||||
|
||||
:param types: An iterable of string representations of the ABI types
|
||||
that will be used for encoding e.g. ``('uint256', 'bytes[]',
|
||||
'(int,int)')``
|
||||
:param args: An iterable of python values to be encoded.
|
||||
|
||||
:returns: The head-tail encoded binary representation of the python
|
||||
values in ``args`` as values of the ABI types in ``types``.
|
||||
"""
|
||||
warnings.warn(
|
||||
"abi.encode_abi() and abi.encode_abi_packed() are deprecated and will be "
|
||||
"removed in version 4.0.0 in favor of abi.encode() and "
|
||||
"abi.encode_packed(), respectively",
|
||||
category=DeprecationWarning,
|
||||
)
|
||||
return self.encode(types, args)
|
||||
|
||||
def encode(self, types, args):
|
||||
encoders = [self._registry.get_encoder(type_str) for type_str in types]
|
||||
|
||||
encoder = TupleEncoder(encoders=encoders)
|
||||
|
||||
return encoder(args)
|
||||
|
||||
def is_encodable(self, typ: TypeStr, arg: Any) -> bool:
|
||||
"""
|
||||
Determines if the python value ``arg`` is encodable as a value of the
|
||||
ABI type ``typ``.
|
||||
|
||||
:param typ: A string representation for the ABI type against which the
|
||||
python value ``arg`` will be checked e.g. ``'uint256'``,
|
||||
``'bytes[]'``, ``'(int,int)'``, etc.
|
||||
:param arg: The python value whose encodability should be checked.
|
||||
|
||||
:returns: ``True`` if ``arg`` is encodable as a value of the ABI type
|
||||
``typ``. Otherwise, ``False``.
|
||||
"""
|
||||
encoder = self._registry.get_encoder(typ)
|
||||
|
||||
try:
|
||||
encoder.validate_value(arg)
|
||||
except EncodingError:
|
||||
return False
|
||||
except AttributeError:
|
||||
try:
|
||||
encoder(arg)
|
||||
except EncodingError:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def is_encodable_type(self, typ: TypeStr) -> bool:
|
||||
"""
|
||||
Returns ``True`` if values for the ABI type ``typ`` can be encoded by
|
||||
this codec.
|
||||
|
||||
:param typ: A string representation for the ABI type that will be
|
||||
checked for encodability e.g. ``'uint256'``, ``'bytes[]'``,
|
||||
``'(int,int)'``, etc.
|
||||
|
||||
:returns: ``True`` if values for ``typ`` can be encoded by this codec.
|
||||
Otherwise, ``False``.
|
||||
"""
|
||||
return self._registry.has_encoder(typ)
|
||||
|
||||
|
||||
class ABIDecoder(BaseABICoder):
|
||||
"""
|
||||
Wraps a registry to provide last-mile decoding functionality.
|
||||
"""
|
||||
|
||||
stream_class = ContextFramesBytesIO
|
||||
|
||||
def decode_single(self, typ: TypeStr, data: Decodable) -> Any:
|
||||
"""
|
||||
Decodes the binary value ``data`` of the ABI type ``typ`` into its
|
||||
equivalent python value.
|
||||
|
||||
:param typ: The string representation of the ABI type that will be used for
|
||||
decoding e.g. ``'uint256'``, ``'bytes[]'``, ``'(int,int)'``, etc.
|
||||
:param data: The binary value to be decoded.
|
||||
|
||||
:returns: The equivalent python value of the ABI value represented in
|
||||
``data``.
|
||||
"""
|
||||
warnings.warn(
|
||||
"abi.decode_single() is deprecated and will be removed in version 4.0.0 "
|
||||
"in favor of abi.decode()",
|
||||
category=DeprecationWarning,
|
||||
)
|
||||
|
||||
if not is_bytes(data):
|
||||
raise TypeError(
|
||||
"The `data` value must be of bytes type. Got {0}".format(type(data))
|
||||
)
|
||||
|
||||
decoder = self._registry.get_decoder(typ)
|
||||
stream = self.stream_class(data)
|
||||
|
||||
return decoder(stream)
|
||||
|
||||
def decode_abi(self, types: Iterable[TypeStr], data: Decodable) -> Tuple[Any, ...]:
|
||||
"""
|
||||
Decodes the binary value ``data`` as a sequence of values of the ABI types
|
||||
in ``types`` via the head-tail mechanism into a tuple of equivalent python
|
||||
values.
|
||||
|
||||
:param types: An iterable of string representations of the ABI types that
|
||||
will be used for decoding e.g. ``('uint256', 'bytes[]', '(int,int)')``
|
||||
:param data: The binary value to be decoded.
|
||||
|
||||
:returns: A tuple of equivalent python values for the ABI values
|
||||
represented in ``data``.
|
||||
"""
|
||||
warnings.warn(
|
||||
"abi.decode_abi() is deprecated and will be removed in version 4.0.0 in "
|
||||
"favor of abi.decode()",
|
||||
category=DeprecationWarning,
|
||||
)
|
||||
return self.decode(types, data)
|
||||
|
||||
def decode(self, types, data):
|
||||
if not is_bytes(data):
|
||||
raise TypeError(
|
||||
f"The `data` value must be of bytes type. Got {type(data)}"
|
||||
)
|
||||
|
||||
decoders = [self._registry.get_decoder(type_str) for type_str in types]
|
||||
|
||||
decoder = TupleDecoder(decoders=decoders)
|
||||
stream = self.stream_class(data)
|
||||
|
||||
return decoder(stream)
|
||||
|
||||
|
||||
class ABICodec(ABIEncoder, ABIDecoder):
|
||||
pass
|
||||
Reference in New Issue
Block a user