def string(self): bytez, bytez_length = string_to_bytes(self.expr.s) placeholder = self.context.new_placeholder(ByteArrayType(bytez_length)) seq = [] seq.append(['mstore', placeholder, bytez_length]) for i in range(0, len(bytez), 32): seq.append(['mstore', ['add', placeholder, i + 32], bytes_to_int((bytez + b'\x00' * 31)[i: i + 32])]) return LLLnode.from_list(['seq'] + seq + [placeholder], typ=ByteArrayType(bytez_length), location='memory', pos=getpos(self.expr), annotation='Create ByteArray: %s' % bytez)
def create_with_code_of(expr, args, kwargs, context): value = kwargs['value'] if value != zero_value: enforce_units(value.typ, get_keyword(expr, 'value'), BaseType('uint256', {'wei': 1})) if context.is_constant: raise ConstancyViolationException( "Cannot make calls from a constant function", expr) placeholder = context.new_placeholder(ByteArrayType(96)) kode = b'`.`\x0c`\x009`.`\x00\xf36`\x00`\x007a\x10\x00`\x006`\x00s\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Z\xf4\x15XWa\x10\x00`\x00\xf3' assert len(kode) <= 64 high = bytes_to_int(kode[:32]) low = bytes_to_int((kode + b'\x00' * 32)[47:79]) return LLLnode.from_list([ 'seq', ['mstore', placeholder, high], ['mstore', ['add', placeholder, 27], ['mul', args[0], 2**96]], ['mstore', ['add', placeholder, 47], low], ['clamp_nonzero', ['create', value, placeholder, 64]] ], typ=BaseType('address'), pos=getpos(expr), add_gas_estimate=10000)
def from_declaration(cls, code, custom_units=None): name = code.target.id pos = 0 if not is_varname_valid(name, custom_units=custom_units): raise EventDeclarationException("Event name invalid: " + name) # Determine the arguments, expects something of the form def foo(arg1: num, arg2: num ... args = [] indexed_list = [] topics_count = 1 if code.annotation.args: keys = code.annotation.args[0].keys values = code.annotation.args[0].values for i in range(len(keys)): typ = values[i] arg = keys[i].id is_indexed = False # Check to see if argument is a topic if isinstance(typ, ast.Call) and typ.func.id == 'indexed': typ = values[i].args[0] indexed_list.append(True) topics_count += 1 is_indexed = True else: indexed_list.append(False) if isinstance(typ, ast.Subscript) and getattr(typ.value, 'id', None) == 'bytes' and typ.slice.value.n > 32 and is_indexed: raise EventDeclarationException("Indexed arguments are limited to 32 bytes") if topics_count > 4: raise EventDeclarationException("Maximum of 3 topics {} given".format(topics_count - 1), arg) if not isinstance(arg, str): raise VariableDeclarationException("Argument name invalid", arg) if not typ: raise InvalidTypeException("Argument must have type", arg) if not is_varname_valid(arg, custom_units): raise VariableDeclarationException("Argument name invalid or reserved: " + arg, arg) if arg in (x.name for x in args): raise VariableDeclarationException("Duplicate function argument name: " + arg, arg) parsed_type = parse_type(typ, None, custom_units=custom_units) args.append(VariableRecord(arg, pos, parsed_type, False)) if isinstance(parsed_type, ByteArrayType): pos += ceil32(typ.slice.value.n) else: pos += get_size_of_type(parsed_type) * 32 sig = name + '(' + ','.join([canonicalize_type(arg.typ, indexed_list[pos]) for pos, arg in enumerate(args)]) + ')' # noqa F812 event_id = bytes_to_int(sha3(bytes(sig, 'utf-8'))) return cls(name, args, indexed_list, event_id, sig)
def _sha3(expr, args, kwargs, context): sub = args[0] # Can hash literals if isinstance(sub, bytes): return LLLnode.from_list(bytes_to_int(sha3(sub)), typ=BaseType('bytes32'), pos=getpos(expr)) # Can hash bytes32 objects if is_base_type(sub.typ, 'bytes32'): return LLLnode.from_list([ 'seq', ['mstore', MemoryPositions.FREE_VAR_SPACE, sub], ['sha3', MemoryPositions.FREE_VAR_SPACE, 32] ], typ=BaseType('bytes32'), pos=getpos(expr)) # Copy the data to an in-memory array if sub.location == "memory": # If we are hashing a value in memory, no need to copy it, just hash in-place return LLLnode.from_list([ 'with', '_sub', sub, ['sha3', ['add', '_sub', 32], ['mload', '_sub']] ], typ=BaseType('bytes32'), pos=getpos(expr)) elif sub.location == "storage": lengetter = LLLnode.from_list(['sload', ['sha3_32', '_sub']], typ=BaseType('int128')) else: # This should never happen, but just left here for future compiler-writers. raise Exception("Unsupported location: %s" % sub.location) # pragma: no test placeholder = context.new_placeholder(sub.typ) placeholder_node = LLLnode.from_list(placeholder, typ=sub.typ, location='memory') copier = make_byte_array_copier( placeholder_node, LLLnode.from_list('_sub', typ=sub.typ, location=sub.location)) return LLLnode.from_list([ 'with', '_sub', sub, ['seq', copier, ['sha3', ['add', placeholder, 32], lengetter]] ], typ=BaseType('bytes32'), pos=getpos(expr))
def pack_logging_topics(event_id, args, expected_topics, context, pos): topics = [event_id] for pos, expected_topic in enumerate(expected_topics): expected_type = expected_topic.typ arg = args[pos] value = parse_expr(arg, context) arg_type = value.typ if isinstance(arg_type, ByteArrayType) and isinstance( expected_type, ByteArrayType): if arg_type.maxlen > expected_type.maxlen: raise TypeMismatchException( "Topic input bytes are too big: %r %r" % (arg_type, expected_type), pos) if isinstance(arg, ast.Str): bytez, bytez_length = string_to_bytes(arg.s) if len(bytez) > 32: raise InvalidLiteralException( "Can only log a maximum of 32 bytes at a time.", pos) topics.append( bytes_to_int(bytez + b'\x00' * (32 - bytez_length))) else: if value.location == "memory": size = ['mload', value] elif value.location == "storage": size = ['sload', ['sha3_32', value]] topics.append(byte_array_to_num(value, arg, 'uint256', size)) else: value = unwrap_location(value) value = base_type_conversion(value, arg_type, expected_type, pos=pos) topics.append(value) return topics