web3.py/web3/eth_abi/abi.py
2017-05-18 18:26:03 -04:00

109 lines
2.9 KiB
Python
Executable File

"""
Vendored from `pyethereum.abi`
"""
import warnings
from io import BytesIO
from ..eth_utils import (
is_text,
force_bytes,
remove_0x_prefix,
decode_hex,
)
from decoding import (
get_single_decoder,
get_multi_decoder,
)
from encoding import (
get_single_encoder,
get_multi_encoder,
)
from utils.parsing import (
process_type,
)
def encode_single(typ, arg):
try:
base, sub, arrlist = typ
except ValueError:
base, sub, arrlist = process_type(typ)
if is_text(arg):
arg = force_bytes(arg)
encoder = get_single_encoder(base, sub, arrlist)
return encoder(arg)
def encode_abi(types, args):
processed_types = [process_type(typ) for typ in types]
encoder = get_multi_encoder(processed_types)
return encoder(args)
HEX_CHARS = b'1234567890abcdef'
def is_hex_encoded_value(v):
if not remove_0x_prefix(force_bytes(v)).lower().strip(HEX_CHARS) == b'':
return False
if len(remove_0x_prefix(v)) % 64 and len(remove_0x_prefix(v)) % 40:
return False
return True
# Decodes a single base datum
def decode_single(typ, data):
if is_hex_encoded_value(data):
warnings.warn(DeprecationWarning(
"Automatic inference of hex encoded data has been deprecated. "
"Please adjust your code to ensure that the data argument for "
"`decode_single` is a byte string"
))
data = decode_hex(remove_0x_prefix(data))
if is_text(data):
warnings.warn(DeprecationWarning(
"Automatic conversion of encoded data to bytes has been deprecated. "
"Please adjust your code to ensure that the data argument for "
"`decode_single` is a byte string"
))
data = force_bytes(data)
try:
base, sub, arrlist = typ
except ValueError:
base, sub, arrlist = process_type(typ)
decoder = get_single_decoder(base, sub, arrlist)
stream = BytesIO(data)
return decoder(stream)
# Decodes multiple arguments using the head/tail mechanism
def decode_abi(types, data):
if is_hex_encoded_value(data):
warnings.warn(DeprecationWarning(
"Automatic inference of hex encoded data has been deprecated. "
"Please adjust your code to ensure that the data argument for "
"`decode_single` is a byte string"
))
data = decode_hex(remove_0x_prefix(data))
if is_text(data):
warnings.warn(DeprecationWarning(
"Automatic conversion of encoded data to bytes has been deprecated. "
"Please adjust your code to ensure that the data argument for "
"`decode_abi` is a byte string"
))
data = force_bytes(data)
processed_types = tuple(process_type(_type) for _type in types)
decoder = get_multi_decoder(processed_types)
stream = BytesIO(data)
return decoder(stream)