def fake_tx(): address = inject_tx( "0xf9035b808506fc23ac0083045f788080b903486103305660006109ac5260006109cc527f0100000000000000000000000000000000000000000000000000000000000000600035046109ec526000610a0c5260006109005260c06109ec51101515585760f86109ec51101561006e5760bf6109ec510336141558576001610a0c52610098565b60013560f76109ec51036020035260005160f66109ec510301361415585760f66109ec5103610a0c525b61022060016064818352015b36610a0c511015156100b557610291565b7f0100000000000000000000000000000000000000000000000000000000000000610a0c5135046109ec526109cc5160206109ac51026040015260016109ac51016109ac5260806109ec51101561013b5760016109cc5161044001526001610a0c516109cc5161046001376001610a0c5101610a0c5260216109cc51016109cc52610281565b60b86109ec5110156101d15760806109ec51036109cc51610440015260806109ec51036001610a0c51016109cc51610460013760816109ec5114156101ac5760807f01000000000000000000000000000000000000000000000000000000000000006001610a0c5101350410151558575b607f6109ec5103610a0c5101610a0c5260606109ec51036109cc51016109cc52610280565b60c06109ec51101561027d576001610a0c51013560b76109ec510360200352600051610a2c526038610a2c5110157f01000000000000000000000000000000000000000000000000000000000000006001610a0c5101350402155857610a2c516109cc516104400152610a2c5160b66109ec5103610a0c51016109cc516104600137610a2c5160b66109ec5103610a0c510101610a0c526020610a2c51016109cc51016109cc5261027f565bfe5b5b5b81516001018083528114156100a4575b5050601f6109ac511115155857602060206109ac5102016109005260206109005103610a0c5261022060016064818352015b6000610a0c5112156102d45761030a565b61090051610a0c516040015101610a0c51610900516104400301526020610a0c5103610a0c5281516001018083528114156102c3575b50506109cc516109005101610420526109cc5161090051016109005161044003f35b61000461033003610004600039610004610330036000f31b2d4f" ) assert viper_utils.bytes_to_int( address) == viper_utils.RLP_DECODER_ADDRESS return address
def pack_logging_topics(event_id, args, expected_topics, context): topics = [event_id] for pos, expected_topic in enumerate(expected_topics): typ = expected_topic.typ arg = args[pos] value = parse_expr(arg, context) if isinstance(typ, ByteArrayType) and ( isinstance(arg, ast.Str) or (isinstance(arg, ast.Name) and arg.id not in reserved_words)): if value.typ.maxlen > typ.maxlen: raise TypeMismatchException( "Topic input bytes are to big: %r %r" % (value.typ, typ)) 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.") topics.append( bytes_to_int(bytez + b'\x00' * (32 - bytez_length))) else: size = context.vars[arg.id].size topics.append(byte_array_to_num(value, arg, 'num256', size)) else: value = unwrap_location(value) value = base_type_conversion(value, value.typ, typ) topics.append(value) return topics
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))
def pack_args_by_32(holder, maxlen, arg, typ, context, placeholder): if isinstance(typ, BaseType): input = parse_expr(arg, context) input = base_type_conversion(input, input.typ, typ) holder.append( LLLnode.from_list(['mstore', placeholder, input], typ=typ, location='memory')) elif isinstance(typ, ByteArrayType): bytez = b'' # String literals if isinstance(arg, ast.Str): if len(arg.s) > typ.maxlen: raise TypeMismatchException( "Data input bytes are to big: %r %r" % (len(arg.s), typ)) for c in arg.s: if ord(c) >= 256: raise InvalidLiteralException( "Cannot insert special character %r into byte array" % c) bytez += bytes([ord(c)]) bytez_length = len(bytez) if len(bytez) > 32: raise InvalidLiteralException( "Can only log a maximum of 32 bytes at a time.") holder.append( LLLnode.from_list([ 'mstore', placeholder, bytes_to_int(bytez + b'\x00' * (32 - bytez_length)) ], typ=typ, location='memory')) # Variables else: input = parse_expr(arg, context) if input.typ.maxlen > typ.maxlen: raise TypeMismatchException( "Data input bytes are to big: %r %r" % (input.typ, typ)) if arg.id in context.vars: size = context.vars[arg.id].size holder.append( LLLnode.from_list([ 'mstore', placeholder, byte_array_to_num(parse_expr(arg, context), arg, 'num256', size) ], typ=typ, location='memory')) elif isinstance(typ, ListType): maxlen += (typ.count - 1) * 32 typ = typ.subtype holder, maxlen = pack_args_by_32(holder, maxlen, arg.elts[0], typ, context, placeholder) for j, arg2 in enumerate(arg.elts[1:]): holder, maxlen = pack_args_by_32( holder, maxlen, arg2, typ, context, context.new_placeholder(BaseType(32))) return holder, maxlen
def from_declaration(cls, code): name = code.target.id pos = 0 # 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 hasattr( typ, 'left') and typ.left.id == 'bytes' and typ.comparators[ 0].n > 32 and is_indexed: raise VariableDeclarationException( "Indexed arguments are limited to 32 bytes") if topics_count > 4: raise VariableDeclarationException( "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): 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) args.append(VariableRecord(arg, pos, parsed_type, False)) if isinstance(parsed_type, ByteArrayType): pos += ceil32(typ.comparators[0].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) ]) + ')' event_id = bytes_to_int(sha3(bytes(sig, 'utf-8'))) return cls(name, args, indexed_list, event_id, sig)
def pack_args_by_32(holder, maxlen, arg, typ, context, placeholder): if isinstance(typ, BaseType): value = parse_expr(arg, context) value = base_type_conversion(value, value.typ, typ) holder.append( LLLnode.from_list(['mstore', placeholder, value], typ=typ, location='memory')) elif isinstance(typ, ByteArrayType): bytez = b'' # Bytes from Storage if isinstance(arg, ast.Attribute) and arg.value.id == 'self': stor_bytes = context.globals[arg.attr] if stor_bytes.typ.maxlen > 32: raise TypeMismatchException( "Can only log a maximum of 32 bytes at a time.") arg2 = LLLnode.from_list([ 'sload', ['add', ['sha3_32', Expr(arg, context).lll_node], 1] ], typ=BaseType(32)) holder, maxlen = pack_args_by_32( holder, maxlen, arg2, BaseType(32), context, context.new_placeholder(BaseType(32))) # String literals elif isinstance(arg, ast.Str): if len(arg.s) > typ.maxlen: raise TypeMismatchException( "Data input bytes are to big: %r %r" % (len(arg.s), typ)) for c in arg.s: if ord(c) >= 256: raise InvalidLiteralException( "Cannot insert special character %r into byte array" % c) bytez += bytes([ord(c)]) bytez_length = len(bytez) if len(bytez) > 32: raise InvalidLiteralException( "Can only log a maximum of 32 bytes at a time.") holder.append( LLLnode.from_list([ 'mstore', placeholder, bytes_to_int(bytez + b'\x00' * (32 - bytez_length)) ], typ=typ, location='memory')) # Variables else: value = parse_expr(arg, context) if value.typ.maxlen > typ.maxlen: raise TypeMismatchException( "Data input bytes are to big: %r %r" % (value.typ, typ)) holder.append( LLLnode.from_list( ['mstore', placeholder, ['mload', ['add', value, 32]]], typ=typ, location='memory')) elif isinstance(typ, ListType): maxlen += (typ.count - 1) * 32 typ = typ.subtype def check_list_type_match(provided): # Check list types match. if provided != typ: raise TypeMismatchException( "Log list type '%s' does not match provided, expected '%s'" % (provided, typ)) # List from storage if isinstance(arg, ast.Attribute) and arg.value.id == 'self': stor_list = context.globals[arg.attr] check_list_type_match(stor_list.typ.subtype) size = stor_list.typ.count for offset in range(0, size): arg2 = LLLnode.from_list([ 'sload', ['add', ['sha3_32', Expr(arg, context).lll_node], offset] ], typ=typ) holder, maxlen = pack_args_by_32( holder, maxlen, arg2, typ, context, context.new_placeholder(BaseType(32))) # List from variable. elif isinstance(arg, ast.Name): size = context.vars[arg.id].size pos = context.vars[arg.id].pos check_list_type_match(context.vars[arg.id].typ.subtype) for i in range(0, size): offset = 32 * i arg2 = LLLnode.from_list(pos + offset, typ=typ, location='memory') holder, maxlen = pack_args_by_32( holder, maxlen, arg2, typ, context, context.new_placeholder(BaseType(32))) # is list literal. else: holder, maxlen = pack_args_by_32(holder, maxlen, arg.elts[0], typ, context, placeholder) for j, arg2 in enumerate(arg.elts[1:]): holder, maxlen = pack_args_by_32( holder, maxlen, arg2, typ, context, context.new_placeholder(BaseType(32))) return holder, maxlen
tx = rlp.decode(ethereum_utils.decode_hex(txhex[2:]), transactions.Transaction) chain.head_state.set_balance(tx.sender, tx.startgas * tx.gasprice) chain.chain.state.set_balance(tx.sender, tx.startgas * tx.gasprice) messages.apply_transaction(chain.head_state, tx) chain.block.transactions.append(tx) contract_address = ethereum_utils.sha3(rlp.encode([tx.sender, 0]))[12:] assert chain.head_state.get_code(contract_address) chain.mine(1) return contract_address _rlp_decoder_address = inject_tx( "0xf9035b808506fc23ac0083045ef88080b903486103305660006109ac5260006109cc527f0100000000000000000000000000000000000000000000000000000000000000600035046109ec526000610a0c5260006109005260c06109ec51101515585760f86109ec51101561006e5760bf6109ec510336141558576001610a0c52610098565b60013560f76109ec51036020035260005160f66109ec510301361415585760f66109ec5103610a0c525b61010060016064818352015b36610a0c511015156100b557610291565b7f0100000000000000000000000000000000000000000000000000000000000000610a0c5135046109ec526109cc5160206109ac51026040015260016109ac51016109ac5260806109ec51101561013b5760016109cc5161044001526001610a0c516109cc5161046001376001610a0c5101610a0c5260216109cc51016109cc52610281565b60b86109ec5110156101d15760806109ec51036109cc51610440015260806109ec51036001610a0c51016109cc51610460013760816109ec5114156101ac5760807f01000000000000000000000000000000000000000000000000000000000000006001610a0c5101350410151558575b607f6109ec5103610a0c5101610a0c5260606109ec51036109cc51016109cc52610280565b60c06109ec51101561027d576001610a0c51013560b76109ec510360200352600051610a2c526038610a2c5110157f01000000000000000000000000000000000000000000000000000000000000006001610a0c5101350402155857610a2c516109cc516104400152610a2c5160b66109ec5103610a0c51016109cc516104600137610a2c5160b66109ec5103610a0c510101610a0c526020610a2c51016109cc51016109cc5261027f565bfe5b5b5b81516001018083528114156100a4575b5050601f6109ac511115155857602060206109ac5102016109005260206109005103610a0c5261010060016064818352015b6000610a0c5112156102d45761030a565b61090051610a0c516040015101610a0c51610900516104400301526020610a0c5103610a0c5281516001018083528114156102c3575b50506109cc516109005101610420526109cc5161090051016109005161044003f35b61000461033003610004600039610004610330036000f31b2d4f" ) assert utils.bytes_to_int(_rlp_decoder_address) == utils.RLP_DECODER_ADDRESS chain.head_state.gas_limit = 10**9 def check_gas(code, func=None, num_txs=1): if func: gas_estimate = tester.languages['viper'].gas_estimate(code)[func] else: gas_estimate = sum( tester.languages['viper'].gas_estimate(code).values()) gas_actual = chain.head_state.receipts[-1].gas_used \ - chain.head_state.receipts[-1-num_txs].gas_used \ - chain.last_tx.intrinsic_gas_used*num_txs # Computed upper bound on the gas consumption should
def pack_args_by_32(holder, maxlen, arg, typ, context, placeholder): if isinstance(typ, BaseType): value = parse_expr(arg, context) value = base_type_conversion(value, value.typ, typ) holder.append( LLLnode.from_list(['mstore', placeholder, value], typ=typ, location='memory')) elif isinstance(typ, ByteArrayType): bytez = b'' # String literals if isinstance(arg, ast.Str): if len(arg.s) > typ.maxlen: raise TypeMismatchException( "Data input bytes are to big: %r %r" % (len(arg.s), typ)) for c in arg.s: if ord(c) >= 256: raise InvalidLiteralException( "Cannot insert special character %r into byte array" % c) bytez += bytes([ord(c)]) bytez_length = len(bytez) if len(bytez) > 32: raise InvalidLiteralException( "Can only log a maximum of 32 bytes at a time.") holder.append( LLLnode.from_list([ 'mstore', placeholder, bytes_to_int(bytez + b'\x00' * (32 - bytez_length)) ], typ=typ, location='memory')) # Variables else: value = parse_expr(arg, context) if value.typ.maxlen > typ.maxlen: raise TypeMismatchException( "Data input bytes are to big: %r %r" % (value.typ, typ)) holder.append( LLLnode.from_list( ['mstore', placeholder, ['mload', ['add', value, 32]]], typ=typ, location='memory')) elif isinstance(typ, ListType): maxlen += (typ.count - 1) * 32 typ = typ.subtype if isinstance(arg, ast.Name): size = context.vars[arg.id].size pos = context.vars[arg.id].pos for i in range(0, size): offset = 32 * i arg2 = LLLnode.from_list(pos + offset, typ=typ, location='memory') holder, maxlen = pack_args_by_32( holder, maxlen, arg2, typ, context, context.new_placeholder(BaseType(32))) else: # is list literal. holder, maxlen = pack_args_by_32(holder, maxlen, arg.elts[0], typ, context, placeholder) for j, arg2 in enumerate(arg.elts[1:]): holder, maxlen = pack_args_by_32( holder, maxlen, arg2, typ, context, context.new_placeholder(BaseType(32))) return holder, maxlen