Skip to content

Commit b358371

Browse files
committed
update abi
1 parent 219c098 commit b358371

File tree

1 file changed

+89
-5
lines changed

1 file changed

+89
-5
lines changed

tronapi/common/abi.py

Lines changed: 89 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,34 @@
44
# See License.txt in the project root for license information.
55
# --------------------------------------------------------------------
66

7+
import binascii
78
import itertools
89
import re
910

1011
from collections import (
1112
namedtuple,
1213
)
1314

14-
from eth_abi import is_encodable
15+
from eth_abi import (
16+
encoding,
17+
decoding
18+
)
19+
20+
from eth_abi.codec import ABICodec
21+
from eth_abi.registry import (
22+
BaseEquals,
23+
registry as default_registry,
24+
)
25+
1526
from eth_utils import to_tuple
1627

28+
from trx_utils import (
29+
decode_hex,
30+
is_bytes,
31+
is_text,
32+
to_text
33+
)
34+
1735
from tronapi.common.formatters import recursive_map
1836
from tronapi.exceptions import FallbackNotFound
1937
from tronapi.common.toolz import (
@@ -330,6 +348,72 @@ def filter_by_encodability(args, kwargs, contract_abi):
330348
if check_if_arguments_can_be_encoded(function_abi, args, kwargs)
331349
]
332350

351+
class AcceptsHexStrMixin:
352+
def validate_value(self, value):
353+
if is_text(value):
354+
try:
355+
value = decode_hex(value)
356+
except binascii.Error:
357+
self.invalidate_value(
358+
value,
359+
msg='invalid hex string',
360+
)
361+
362+
super().validate_value(value)
363+
364+
365+
class ByteStringEncoder(AcceptsHexStrMixin, encoding.ByteStringEncoder):
366+
pass
367+
368+
369+
class BytesEncoder(AcceptsHexStrMixin, encoding.BytesEncoder):
370+
pass
371+
372+
373+
class TextStringEncoder(encoding.TextStringEncoder):
374+
@classmethod
375+
def validate_value(cls, value):
376+
if is_bytes(value):
377+
try:
378+
value = to_text(value)
379+
except UnicodeDecodeError:
380+
cls.invalidate_value(
381+
value,
382+
msg='not decodable as unicode string',
383+
)
384+
385+
super().validate_value(value)
386+
387+
388+
# We make a copy here just to make sure that eth-abi's default registry is not
389+
# affected by our custom encoder subclasses
390+
registry = default_registry.copy()
391+
392+
registry.unregister('address')
393+
registry.unregister('bytes<M>')
394+
registry.unregister('bytes')
395+
registry.unregister('string')
396+
397+
registry.register(
398+
BaseEquals('bytes', with_sub=True),
399+
BytesEncoder, decoding.BytesDecoder,
400+
label='bytes<M>',
401+
)
402+
403+
registry.register(
404+
BaseEquals('bytes', with_sub=False),
405+
ByteStringEncoder, decoding.ByteStringDecoder,
406+
label='bytes',
407+
)
408+
registry.register(
409+
BaseEquals('string'),
410+
TextStringEncoder, decoding.StringDecoder,
411+
label='string',
412+
)
413+
414+
codec = ABICodec(registry)
415+
is_encodable = codec.is_encodable
416+
333417

334418
def check_if_arguments_can_be_encoded(function_abi, args, kwargs):
335419
try:
@@ -483,10 +567,10 @@ def abi_data_tree(types, data):
483567

484568
@curry
485569
def data_tree_map(func, data_tree):
486-
'''
570+
"""
487571
Map func to every ABITypedData element in the tree. func will
488572
receive two args: abi_type, and data
489-
'''
573+
"""
490574

491575
def map_to_typed_data(elements):
492576
if isinstance(elements, ABITypedData) and elements.abi_type is not None:
@@ -498,7 +582,7 @@ def map_to_typed_data(elements):
498582

499583

500584
class ABITypedData(namedtuple('ABITypedData', 'abi_type, data')):
501-
'''
585+
"""
502586
This class marks data as having a certain ABI-type.
503587
504588
>>> a1 = ABITypedData(['address', addr1])
@@ -514,7 +598,7 @@ class ABITypedData(namedtuple('ABITypedData', 'abi_type, data')):
514598
Unlike a typical `namedtuple`, you initialize with a single
515599
positional argument that is iterable, to match the init
516600
interface of all other relevant collections.
517-
'''
601+
"""
518602

519603
def __new__(cls, iterable):
520604
return super().__new__(cls, *iterable)

0 commit comments

Comments
 (0)