def get_create_forwarder_to_bytecode(): from vyper.compile_lll import (assembly_to_evm, num_to_bytearray) code_a = [ 'PUSH1', 0x33, 'PUSH1', 0x0c, 'PUSH1', 0x00, 'CODECOPY', 'PUSH1', 0x33, 'PUSH1', 0x00, 'RETURN', 'CALLDATASIZE', 'PUSH1', 0x00, 'PUSH1', 0x00, 'CALLDATACOPY', 'PUSH2', num_to_bytearray(0x1000), 'PUSH1', 0x00, 'CALLDATASIZE', 'PUSH1', 0x00, 'PUSH20', # [address to delegate to] ] code_b = [ 'GAS', 'DELEGATECALL', 'PUSH1', 0x2c, # jumpdest of whole program. 'JUMPI', 'PUSH1', 0x0, 'DUP1', 'REVERT', 'JUMPDEST', 'PUSH2', num_to_bytearray(0x1000), 'PUSH1', 0x00, 'RETURN' ] return assembly_to_evm(code_a)[0] + (b'\x00' * 20) + assembly_to_evm(code_b)[0]
def transpile(clss, target="deploy"): if target not in ["deploy", "abi", "bytecode", "lll", "vyper", "vy"]: raise ValueError("Unrecognized target for transpilation") if type(clss) is Lll: #todo: need to rework this if target == "bytecode": asm = compile_to_assembly(clss.node) return '0x' + assembly_to_evm(asm).hex() raise ValueError("lll can only be compiled to bytecode for now") vyp = python_to_vyper(clss) if target == "vyper" or target == "vy": return vyp if target == "bytecode": return Bytecode('0x' + compiler.compile(str(vyp)).hex()) if target == "abi": return Abi(compiler.mk_full_signature(str(vyp))) if target == "deploy": abi = Abi(compiler.mk_full_signature(str(vyp))) bytecode = Bytecode('0x' + compiler.compile(str(vyp)).hex()) return Deploy(abi, bytecode) return Lll(optimizer.optimize(parse_to_lll(str(vyp))))
def __compile(code, interface_codes=None, *args, **kwargs): ast = parser.parse_to_ast(code) lll = parser.parse_tree_to_lll(ast, code, interface_codes=interface_codes, runtime_only=kwargs.get( 'bytecode_runtime', False)) opt_lll = optimizer.optimize(lll) asm = compile_lll.compile_to_assembly(opt_lll) def find_nested_opcode(asm_list, key): if key in asm_list: return True else: sublists = [sub for sub in asm_list if isinstance(sub, list)] return any(find_nested_opcode(x, key) for x in sublists) if find_nested_opcode(asm, 'DEBUG'): print('Please note this code contains DEBUG opcode.') print( 'This will only work in a support EVM. This FAIL on any other nodes.' ) c, line_number_map = compile_lll.assembly_to_evm(asm) return c
def generate_validation_code(address): valcode = generate_pure_ecrecover_LLL_source(address) lll_node = LLLnode.from_list(valcode) optimized = optimizer.optimize(lll_node) assembly = compile_lll.compile_to_assembly(optimized) evm = compile_lll.assembly_to_evm(assembly) return evm
def compile_vyper_lll(vyper_code): if vyper_available: lll_node = LLLnode.from_list(vyper_code) assembly = compile_to_assembly(lll_node) code = assembly_to_evm(assembly) return code else: raise ImportError("Vyper package not installed")
def get_source_map(code): asm_list = compile_lll.compile_to_assembly( optimizer.optimize(parser.parse_to_lll(code, runtime_only=True))) c, line_number_map = compile_lll.assembly_to_evm(asm_list) # Sort line_number_map out = OrderedDict() keylist = line_number_map.keys() for k in sorted(keylist): out[k] = line_number_map[k] return out
def lll_compiler(lll, *args, **kwargs): lll = optimizer.optimize(LLLnode.from_list(lll)) bytecode, _ = compile_lll.assembly_to_evm(compile_lll.compile_to_assembly(lll)) abi = kwargs.get('abi') or [] contract = w3.eth.contract(bytecode=bytecode, abi=abi) deploy_transaction = { 'data': contract._encode_constructor_data(args, kwargs) } tx = w3.eth.sendTransaction(deploy_transaction) address = w3.eth.getTransactionReceipt(tx)['contractAddress'] contract = w3.eth.contract(address, abi=abi, bytecode=bytecode, ContractFactoryClass=VyperContract) return contract
def lll_compiler(lll, *args, **kwargs): lll = optimizer.optimize(LLLnode.from_list(lll)) bytecode, _ = compile_lll.assembly_to_evm(compile_lll.compile_to_assembly(lll)) abi = kwargs.get("abi") or [] c = w3.eth.contract(abi=abi, bytecode=bytecode) deploy_transaction = c.constructor() tx_hash = deploy_transaction.transact() address = w3.eth.getTransactionReceipt(tx_hash)["contractAddress"] contract = w3.eth.contract( address, abi=abi, bytecode=bytecode, ContractFactoryClass=VyperContract, ) return contract
def build_source_map_output(compiler_data: CompilerData) -> OrderedDict: _, line_number_map = compile_lll.assembly_to_evm(compiler_data.assembly_runtime) # Sort line_number_map out = OrderedDict() for k in sorted(line_number_map.keys()): out[k] = line_number_map[k] out["pc_pos_map_compressed"] = _compress_source_map( compiler_data.source_code, out["pc_pos_map"], out["pc_jump_map"], compiler_data.source_id, ) out["pc_pos_map"] = dict((k, v) for k, v in out["pc_pos_map"].items() if v) return out
def produce_source_map(code, interface_codes=None): global_ctx = GlobalContext.get_global_context( parser.parse_to_ast(code), interface_codes=interface_codes) asm_list = compile_lll.compile_to_assembly( optimizer.optimize( parse_to_lll(code, runtime_only=True, interface_codes=interface_codes))) c, line_number_map = compile_lll.assembly_to_evm(asm_list) source_map = { "globals": {}, "locals": {}, "line_number_map": line_number_map } source_map["globals"] = { name: serialise_var_rec(var_record) for name, var_record in global_ctx._globals.items() } # Fetch context for each function. lll = parser.parse_tree_to_lll( parser.parse_to_ast(code), code, interface_codes=interface_codes, runtime_only=True, ) contexts = { f.func_name: f.context for f in lll.args[1:] if hasattr(f, "context") } prev_func_name = None for _def in global_ctx._defs: if _def.name != "__init__": func_info = {"from_lineno": _def.lineno, "variables": {}} # set local variables for specific function. context = contexts[_def.name] func_info["variables"] = { var_name: serialise_var_rec(var_rec) for var_name, var_rec in context.vars.items() } source_map["locals"][_def.name] = func_info # set to_lineno if prev_func_name: source_map["locals"][prev_func_name]["to_lineno"] = _def.lineno prev_func_name = _def.name source_map["locals"][_def.name]["to_lineno"] = len(code.splitlines()) return source_map
def generate_bytecode(assembly: list) -> bytes: """ Generate bytecode from assembly instructions. Arguments --------- assembly : list Assembly instructions. Can be deployment or runtime assembly. Returns ------- bytes Final compiled bytecode. """ return compile_lll.assembly_to_evm(assembly)[0]
def get_source_map(code, contract_name, interface_codes=None): asm_list = compile_lll.compile_to_assembly( optimizer.optimize( parser.parse_to_lll(code, runtime_only=True, interface_codes=interface_codes))) c, line_number_map = compile_lll.assembly_to_evm(asm_list) # Sort line_number_map out = OrderedDict() for k in sorted(line_number_map.keys()): out[k] = line_number_map[k] out['pc_pos_map_compressed'] = compress_source_map(code, out['pc_pos_map'], out['pc_jump_map']) out['pc_pos_map'] = dict((k, v) for k, v in out['pc_pos_map'].items() if v) return out
def compile(code, *args, **kwargs): lll = optimizer.optimize(parser.parse_tree_to_lll(parser.parse(code), code, runtime_only=kwargs.get('bytecode_runtime', False))) asm = compile_lll.compile_to_assembly(lll) def find_nested_opcode(asm_list, key): if key in asm_list: return True else: sublists = [sub for sub in asm_list if isinstance(sub, list)] return any([find_nested_opcode(x, key) for x in sublists]) if find_nested_opcode(asm, 'DEBUG'): print('Please not this code contains DEBUG opcode.') print('This will only work in a support EVM. This FAIL on any other nodes.') return compile_lll.assembly_to_evm(asm)
def compile_valcode_to_evm_bytecode(valcode_type, address): valcodes = generate_all_valcodes(address) valcode = valcodes[valcode_type] # We assume bytes are compiled evm code if type(valcode) is bytes: return valcode # We assume lists are uncompiled LLL seqs elif type(valcode) is list: lll_node = LLLnode.from_list(valcode) optimized = optimizer.optimize(lll_node) assembly = compile_lll.compile_to_assembly(optimized) evm = compile_lll.assembly_to_evm(assembly) return evm # Any other types are unacceptable else: raise ValueError('Valcode must be of types list (uncompiled LLL), or ' 'bytes (compiled bytecode). Given: ' '{}'.format(type(valcode)))
def produce_source_map(code): global_ctx = GlobalContext.get_global_context(parser.parse_to_ast(code)) asm_list = compile_lll.compile_to_assembly( optimizer.optimize(parse_to_lll(code, runtime_only=True))) c, line_number_map = compile_lll.assembly_to_evm(asm_list) source_map = { 'globals': {}, 'locals': {}, 'line_number_map': line_number_map } source_map['globals'] = { name: serialise_var_rec(var_record) for name, var_record in global_ctx._globals.items() } # Fetch context for each function. lll = parser.parse_tree_to_lll(parser.parse_to_ast(code), code, runtime_only=True) contexts = { f.func_name: f.context for f in lll.args[1:] if hasattr(f, 'context') } prev_func_name = None for _def in global_ctx._defs: if _def.name != '__init__': func_info = {'from_lineno': _def.lineno, 'variables': {}} # set local variables for specific function. context = contexts[_def.name] func_info['variables'] = { var_name: serialise_var_rec(var_rec) for var_name, var_rec in context.vars.items() } source_map['locals'][_def.name] = func_info # set to_lineno if prev_func_name: source_map['locals'][prev_func_name]['to_lineno'] = _def.lineno prev_func_name = _def.name source_map['locals'][_def.name]['to_lineno'] = len(code.splitlines()) return source_map
def compile_to_lll(input_file, output_formats, show_gas_estimates=False): with open(input_file) as fh: s_expressions = parse_s_exp(fh.read()) if show_gas_estimates: LLLnode.repr_show_gas = True compiler_data = {} lll = LLLnode.from_list(s_expressions[0]) if "ir" in output_formats: compiler_data["ir"] = lll if "opt_ir" in output_formats: compiler_data["opt_ir"] = optimizer.optimize(lll) asm = compile_lll.compile_to_assembly(lll) if "asm" in output_formats: compiler_data["asm"] = asm if "bytecode" in output_formats: (bytecode, _srcmap) = compile_lll.assembly_to_evm(asm) compiler_data["bytecode"] = "0x" + bytecode.hex() return compiler_data
'mstore', add(sub(data, ['mload', position_offset]), ['mload', i]), add(['mload', add(positions, ['mload', i])], ['mload', position_offset]) ], # ~mstore(data - positionOffset + i, ~mload(positions + i) + positionOffset) ['mstore', i, sub(['mload', i], 32)], ] ], [ 'mstore', sub(data, 32), add(['mload', position_offset], ['mload', data_pos]) ], [ 'return', sub(data, ['mload', position_offset]), add(['mload', position_offset], ['mload', data_pos]) ] ], [0] ] ] ]) rlp_decoder_lll = optimizer.optimize(rlp_decoder_lll) rlp_decoder_bytes, _ = compile_lll.assembly_to_evm( compile_lll.compile_to_assembly(rlp_decoder_lll))
def test_pc_debugger(): debugger_lll = ['seq_unchecked', ['mstore', 0, 32], ['pc_debugger']] lll_nodes = LLLnode.from_list(debugger_lll) _, line_number_map = compile_lll.assembly_to_evm( compile_lll.compile_to_assembly(lll_nodes)) assert line_number_map['pc_breakpoints'][0] == 5
def test_pc_debugger(): debugger_lll = ["seq_unchecked", ["mstore", 0, 32], ["pc_debugger"]] lll_nodes = LLLnode.from_list(debugger_lll) _, line_number_map = compile_lll.assembly_to_evm( compile_lll.compile_to_assembly(lll_nodes)) assert line_number_map["pc_breakpoints"][0] == 5
def lll_to_evm(lll): return compile_lll.assembly_to_evm(compile_lll.compile_to_assembly(optimizer.optimize(lll)))
def compile_vyper_lll(vyper_code): lll_node = LLLnode.from_list(vyper_code) assembly = compile_to_assembly(lll_node) code = assembly_to_evm(assembly) return code
def lll_compiler(lll): lll = optimizer.optimize(LLLnode.from_list(lll)) byte_code = compile_lll.assembly_to_evm(compile_lll.compile_to_assembly(lll)) t.s.tx(to=b'', data=byte_code)
def compile_vyper_lll(vyper_code: List[Any]) -> Tuple[bytes, Dict[str, Any]]: lll_node = LLLnode.from_list(vyper_code) assembly = compile_to_assembly(lll_node) code = assembly_to_evm(assembly) return code