def decode_single(typ, data): try: base, sub, arrlist = typ except ValueError: base, sub, arrlist = process_type(typ) if is_hex_encoded_value(data): data = decode_hex(strip_0x_prefix(data)) if base == 'address': return encode_hex(data[12:]) elif base == 'hash': return data[32 - int(sub):] elif base == 'string' or base == 'bytes': if len(sub): return data[:int(sub)] else: l = big_endian_to_int(data[0:32]) return data[32:][:l] elif base == 'uint': return big_endian_to_int(data) elif base == 'int': o = big_endian_to_int(data) return (o - 2**int(sub)) if o >= 2**(int(sub) - 1) else o elif base == 'ureal': high, low = [int(x) for x in sub.split('x')] return big_endian_to_int(data) * 1.0 / 2**low elif base == 'real': high, low = [int(x) for x in sub.split('x')] o = big_endian_to_int(data) i = (o - 2**(high + low)) if o >= 2**(high + low - 1) else o return (i * 1.0 / 2**low) elif base == 'bool': return bool(int(encode_hex(data), 16))
def dec(typ, arg): base, sub, arrlist = typ sz = get_size(typ) # Dynamic-sized strings are encoded as <len(str)> + <str> if base in ('string', 'bytes') and not sub: L = big_endian_to_int(arg[:32]) if len(arg[32:]) != ceil32(L): raise ValueError("Wrong data size for string/bytes object") return arg[32:][:L] # Dynamic-sized arrays elif sz is None: L = big_endian_to_int(arg[:32]) subtyp = base, sub, arrlist[:-1] subsize = get_size(subtyp) # If children are dynamic, use the head/tail mechanism. Fortunately, # here the code is simpler since we do not have to worry about # mixed dynamic and static children, as we do in the top-level multi-arg # case if subsize is None: if len(arg) < 32 + 32 * L: raise DecodingError("Not enough data for head") start_positions = [ big_endian_to_int(arg[32 + 32 * i:64 + 32 * i]) for i in range(L) ] + [len(arg)] outs = [ arg[start_positions[i]:start_positions[i + 1]] for i in range(L) ] return [dec(subtyp, out) for out in outs] # If children are static, then grab the data slice for each one and # sequentially decode them manually else: return [ dec(subtyp, arg[32 + subsize * i:32 + subsize * (i + 1)]) for i in range(L) ] # Static-sized arrays: decode piece-by-piece elif len(arrlist): L = arrlist[-1][0] subtyp = base, sub, arrlist[:-1] subsize = get_size(subtyp) return [ dec(subtyp, arg[subsize * i:subsize * (i + 1)]) for i in range(L) ] else: return decode_single(typ, arg)
def dec(typ, arg): base, sub, arrlist = typ sz = get_size(typ) # Dynamic-sized strings are encoded as <len(str)> + <str> if base in ('string', 'bytes') and not sub: L = big_endian_to_int(arg[:32]) if len(arg[32:]) != ceil32(L): raise ValueError("Wrong data size for string/bytes object") return arg[32:][:L] # Dynamic-sized arrays elif sz is None: L = big_endian_to_int(arg[:32]) subtyp = base, sub, arrlist[:-1] subsize = get_size(subtyp) # If children are dynamic, use the head/tail mechanism. Fortunately, # here the code is simpler since we do not have to worry about # mixed dynamic and static children, as we do in the top-level multi-arg # case if subsize is None: if len(arg) < 32 + 32 * L: raise DecodingError("Not enough data for head") start_positions = [big_endian_to_int(arg[32 + 32 * i: 64 + 32 * i]) for i in range(L)] + [len(arg)] outs = [arg[start_positions[i]: start_positions[i + 1]] for i in range(L)] return [dec(subtyp, out) for out in outs] # If children are static, then grab the data slice for each one and # sequentially decode them manually else: return [dec(subtyp, arg[32 + subsize * i: 32 + subsize * (i + 1)]) for i in range(L)] # Static-sized arrays: decode piece-by-piece elif len(arrlist): L = arrlist[-1][0] subtyp = base, sub, arrlist[:-1] subsize = get_size(subtyp) return [dec(subtyp, arg[subsize * i:subsize * (i + 1)]) for i in range(L)] else: return decode_single(typ, arg)
def decode_abi(types, data): if is_hex_encoded_value(data): data = decode_hex(strip_0x_prefix(data)) # Process types proctypes = [process_type(typ) for typ in types] # Get sizes of everything sizes = [get_size(typ) for typ in proctypes] # Initialize array of outputs outs = [None] * len(types) # Initialize array of start positions start_positions = [None] * len(types) + [len(data)] # If a type is static, grab the data directly, otherwise record # its start position pos = 0 for i, typ in enumerate(types): if sizes[i] is None: start_positions[i] = big_endian_to_int(data[pos:pos + 32]) j = i - 1 while j >= 0 and start_positions[j] is None: start_positions[j] = start_positions[i] j -= 1 pos += 32 else: outs[i] = data[pos:pos + sizes[i]] pos += sizes[i] # We add a start position equal to the length of the entire data # for convenience. j = len(types) - 1 while j >= 0 and start_positions[j] is None: start_positions[j] = start_positions[len(types)] j -= 1 if pos > len(data): raise DecodingError("Not enough data for head") # Grab the data for tail arguments using the start positions # calculated above for i, typ in enumerate(types): if sizes[i] is None: offset = start_positions[i] next_offset = start_positions[i + 1] outs[i] = data[offset:next_offset] # Recursively decode them all return [dec(proctypes[i], outs[i]) for i in range(len(outs))]
def decint(n, signed=False): if isinstance(n, str): n = to_string(n) if is_numeric(n): min, max = (-TT255, TT255 - 1) if signed else (0, TT256M1) if n > max or n < min: raise EncodingError("Number out of range: %r" % n) return n elif is_string(n): if len(n) == 40: n = decode_hex(n) if len(n) > 32: raise EncodingError("String too long: %r" % n) i = big_endian_to_int(n) return (i - TT256) if signed and i >= TT255 else i elif n is True: return 1 elif n is False or n is None: return 0 else: raise EncodingError("Cannot encode integer: %r" % n)
def abi_signature(self): """ Compute the bytes4 signature for the object. """ return big_endian_to_int(sha3(self.signature)[:4])
def event_topic(self): return hex(big_endian_to_int(utils.sha3(self.signature))).strip('L')
def event_topic(self): return hex(big_endian_to_int( utils.sha3(self.signature) )).strip('L')