Пример #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
Пример #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))))
Пример #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
Пример #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
Пример #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
Пример #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)
Пример #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
Пример #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
Пример #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
Пример #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
Пример #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
Пример #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
Пример #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
Пример #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)
Пример #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
Пример #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)))
Пример #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
Пример #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)))
Пример #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':
Пример #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))))
Пример #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))
Пример #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))
Пример #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)
Пример #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
Пример #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)
Пример #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):