def test_sha3_32(): lll = ["sha3_32", 0] evm = [ "PUSH1", 0, "PUSH1", 192, "MSTORE", "PUSH1", 32, "PUSH1", 192, "SHA3" ] assert compile_lll.compile_to_assembly(LLLnode.from_list(lll)) == evm assert compile_lll.compile_to_assembly( optimizer.optimize(LLLnode.from_list(lll))) == evm
def test_sha3_32(): lll = ['sha3_32', 0] evm = [ 'PUSH1', 0, 'PUSH1', 192, 'MSTORE', 'PUSH1', 32, 'PUSH1', 192, 'SHA3' ] assert compile_lll.compile_to_assembly(LLLnode.from_list(lll)) == evm assert compile_lll.compile_to_assembly( optimizer.optimize(LLLnode.from_list(lll))) == evm
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 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 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 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_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 generate_assembly(lll_nodes: parser.LLLnode) -> list: """ Generate assembly instructions from LLL. Arguments --------- lll_nodes : str Top-level LLL nodes. Can be deployment or runtime LLL. Returns ------- list List of assembly instructions. """ assembly = compile_lll.compile_to_assembly(lll_nodes) if _find_nested_opcode(assembly, "DEBUG"): warnings.warn( "This code contains DEBUG opcodes! The DEBUG opcode will only work in " "a supported EVM! It will FAIL on all other nodes!") return assembly
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
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
out[k] = line_number_map[k] return out output_formats_map = { 'abi': lambda code: mk_full_signature(code), 'bytecode': lambda code: '0x' + __compile(code).hex(), 'bytecode_runtime': lambda code: '0x' + __compile(code, bytecode_runtime=True).hex(), 'ir': lambda code: optimizer.optimize(parser.parse_to_lll(code)), 'asm': lambda code: get_asm( compile_lll.compile_to_assembly( optimizer.optimize(parser.parse_to_lll(code)))), 'source_map': get_source_map, 'method_identifiers': lambda code: parser.mk_method_identifiers(code) } def compile_codes(codes, output_formats=['bytecode'], output_type='list', exc_handler=None): out = OrderedDict() for contract_name, code in codes.items(): for output_format in output_formats:
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)
['calldatacopy', add(data + 32, ['mload', data_pos]), add(['mload', i], 1), sub(['mload', c], 128)], ['if', ['eq', ['mload', c], 129], ['assert', ['ge', call_data_char(add(['mload', i], 1)), 128]]], ['mstore', i, add(['mload', i], sub(['mload', c], 127))], ['mstore', data_pos, add(['mload', data_pos], sub(['mload', c], 96))]], ['if', ['lt', ['mload', c], 192], ['seq', ['mstore', L, call_data_bytes_as_int(add(['mload', i], 1), sub(['mload', c], 183))], ['assert', ['mul', call_data_char(add(['mload', i], 1)), ['ge', ['mload', L], 56]]], ['mstore', add(data, ['mload', data_pos]), ['mload', L]], ['calldatacopy', add(data + 32, ['mload', data_pos]), add(['mload', i], sub(['mload', c], 182)), ['mload', L]], ['mstore', i, add(add(['mload', i], sub(['mload', c], 182)), ['mload', L])], ['mstore', data_pos, add(['mload', data_pos], add(['mload', L], 32))]], ['invalid']]]]]], ['assert', ['le', ['mload', position_index], 31]], ['mstore', position_offset, add(['mul', ['mload', position_index], 32], 32)], ['mstore', i, sub(['mload', position_offset], 32)], ['repeat', loop_memory_position, 1, 100, ['seq', ['if', ['slt', ['mload', i], 0], 'break'], ['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))
'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 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
'abi': lambda code, contract_name, interface_codes: mk_full_signature( code, interface_codes=interface_codes), 'bytecode': lambda code, contract_name, interface_codes: '0x' + __compile( code, interface_codes=interface_codes).hex(), 'bytecode_runtime': lambda code, contract_name, interface_codes: '0x' + __compile( code, bytecode_runtime=True, interface_codes=interface_codes).hex(), 'ir': lambda code, contract_name, interface_codes: optimizer.optimize( parser.parse_to_lll(code, interface_codes=interface_codes)), 'asm': lambda code, contract_name, interface_codes: get_asm( compile_lll.compile_to_assembly( optimizer.optimize( parser.parse_to_lll(code, interface_codes=interface_codes)))), 'source_map': lambda code, contract_name, interface_codes: get_source_map( code, contract_name, interface_codes=interface_codes), 'method_identifiers': lambda code, contract_name, interface_codes: parser.mk_method_identifiers( code, interface_codes=interface_codes), 'interface': lambda code, contract_name, interface_codes: extract_interface_str( code, contract_name, interface_codes=interface_codes), 'external_interface': lambda code, contract_name, interface_codes: extract_external_interface( code, contract_name, interface_codes=interface_codes), }
def _mk_asm_output(code, contract_name, interface_codes, source_id): return get_asm( compile_lll.compile_to_assembly( optimizer.optimize( parser.parse_to_lll(code, interface_codes=interface_codes))))
interface_codes=interface_codes))) 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 output_formats_map = { 'abi': lambda code, contract_name, interface_codes: mk_full_signature(code, interface_codes=interface_codes), 'bytecode': lambda code, contract_name, interface_codes: '0x' + __compile(code, interface_codes=interface_codes).hex(), 'bytecode_runtime': lambda code, contract_name, interface_codes: '0x' + __compile(code, bytecode_runtime=True, interface_codes=interface_codes).hex(), 'ir': lambda code, contract_name, interface_codes: optimizer.optimize(parser.parse_to_lll(code, interface_codes=interface_codes)), 'asm': lambda code, contract_name, interface_codes: get_asm(compile_lll.compile_to_assembly(optimizer.optimize(parser.parse_to_lll(code, interface_codes=interface_codes)))), 'source_map': lambda code, contract_name, interface_codes: get_source_map(code, contract_name, interface_codes=interface_codes), 'method_identifiers': lambda code, contract_name, interface_codes: parser.mk_method_identifiers(code, interface_codes=interface_codes), 'interface': lambda code, contract_name, interface_codes: extract_interface_str(code, contract_name, interface_codes=interface_codes), 'external_interface': lambda code, contract_name, interface_codes: extract_external_interface(code, contract_name, interface_codes=interface_codes), } def compile_codes(codes, output_formats=['bytecode'], output_type='list', exc_handler=None, interface_codes=None): out = OrderedDict() for contract_name, code in codes.items(): for output_format in output_formats: if output_format not in output_formats_map: raise Exception('Unsupported format type %s.' % output_format)