Example #1
0
def generate_lll_nodes(
        source_code: str,
        global_ctx: GlobalContext) -> Tuple[parser.LLLnode, parser.LLLnode]:
    """
    Generate the intermediate representation (LLL) from the contextualized AST.

    This phase also includes LLL-level optimizations.

    This function returns two values, one for generating deployment bytecode and
    the other for generating runtime bytecode. The remaining compilation phases
    may be called with either value, depending on the desired final output.

    Arguments
    ---------
    source_code : str
        Vyper source code.
    global_ctx : GlobalContext
        Contextualized Vyper AST

    Returns
    -------
    (LLLnode, LLLnode)
        LLL to generate deployment bytecode
        LLL to generate runtime bytecode
    """
    lll_nodes, lll_runtime = parser.parse_tree_to_lll(source_code, global_ctx)
    lll_nodes = optimizer.optimize(lll_nodes)
    lll_runtime = optimizer.optimize(lll_runtime)
    return lll_nodes, lll_runtime
Example #2
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))))
Example #3
0
def get_compiler_gas_estimate(code, func):
    lll_nodes = optimizer.optimize(parse_to_lll(code))
    if func:
        return compiler.utils.build_gas_estimates(lll_nodes)[func] + 22000
    else:
        return sum(
            compiler.utils.build_gas_estimates(lll_nodes).values()) + 22000
Example #4
0
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
Example #5
0
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
Example #6
0
def compile(endpoint):
    if endpoint not in ['compile', 'compile-k']:
        abort(500)
    source = request.form.get('source', '')
    try:
        if endpoint == 'compile':
            abi = compiler.mk_full_signature(source)
            abi_code = 200
        else:
            raise Exception('Not available')
    except Exception as e:
        abi = str(e)
        abi_code = 500
    try:
        if endpoint == 'compile':
            json_abi = json.dumps(compiler.mk_full_signature(source))
            json_abi_code = 200
        else:
            raise Exception('Not available')
    except Exception as e:
        json_abi = str(e)
        json_abi_code = 500
    try:
        if endpoint == 'compile':
            bytecode = '0x' + compiler.compile(source).hex()
            bytecode_code = 200
        else:
            raise Exception('Not available')
    except Exception as e:
        bytecode = str(e)
        bytecode_code = 500
    try:
        if endpoint == 'compile':
            ir = optimizer.optimize(parse_to_lll(source))
            ir = str(ir)
            ir_code = 200
        else:
            raise Exception('Not available')
            #ast = parse(source)
            #print("lala")
            #print(ast)
            #ir = viper2lll(ast)
            #ir_code = 200
    except Exception as e:
        ir = str(e)
        ir_code = 500

    r_dict = {
        'result': {
            'abi': abi,
            'abi_code': abi_code,
            'json': json_abi,
            'json_code': json_abi_code,
            'bytecode': bytecode,
            'bytecode_code': bytecode_code,
            'lll': ir,
            'lll_code': ir_code
        }
    }
    return make_response(jsonify(r_dict), 200)
Example #7
0
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
Example #8
0
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
Example #9
0
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
Example #10
0
 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
Example #11
0
 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
Example #12
0
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
Example #13
0
def gas_estimate(origcode, *args, **kwargs):
    o = {}
    code = optimizer.optimize(parser.parse_to_lll(origcode, *args, **kwargs))

    # Extract the stuff inside the LLL bracket
    if code.value == 'seq':
        if len(code.args) > 0 and code.args[-1].value == 'return':
            code = code.args[-1].args[1].args[0]

    assert code.value == 'seq'
    for arg in code.args:
        if arg.func_name is not None:
            o[arg.func_name] = arg.total_gas
    return o
Example #14
0
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)
Example #15
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
Example #16
0
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)))
Example #17
0
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
Example #18
0
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 lll_to_evm(lll):
    return compile_lll.assembly_to_evm(compile_lll.compile_to_assembly(optimizer.optimize(lll)))
Example #20
0
        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':
Example #21
0
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))))
Example #22
0
def _mk_ir_output(code, contract_name, interface_codes, source_id):
    return optimizer.optimize(
        parser.parse_to_lll(code, interface_codes=interface_codes))
Example #23
0
                            '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))
Example #24
0
                runtime_only=True,
                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)
Example #25
0
def test_lll_compile_fail(lll):
    optimized = optimizer.optimize(LLLnode.from_list(lll[0]))
    optimized.repr_show_gas = True
    hand_optimized = LLLnode.from_list(lll[1])
    hand_optimized.repr_show_gas = True
    assert optimized == hand_optimized
Example #26
0
 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)
Example #27
0
    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: 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):