Example #1
0
def get_input_dict_output_formats(input_dict: Dict, contract_sources: ContractCodes) -> Dict:
    output_formats = {}
    for path, outputs in input_dict['outputSelection'].items():
        if isinstance(outputs, dict):
            # if outputs are given in solc json format, collapse them into a single list
            outputs = set(x for i in outputs.values() for x in i)
        else:
            outputs = set(outputs)

        for key in [i for i in ('evm', 'evm.bytecode', 'evm.deployedBytecode') if i in outputs]:
            outputs.remove(key)
            outputs.update([i for i in TRANSLATE_MAP if i.startswith(key)])
        if '*' in outputs:
            outputs = sorted(TRANSLATE_MAP.values())
        else:
            try:
                outputs = sorted(TRANSLATE_MAP[i] for i in outputs)
            except KeyError as e:
                raise JSONError(f"Invalid outputSelection - {e}")

        if path == "*":
            output_keys = list(contract_sources.keys())
        else:
            output_keys = [_standardize_path(path)]
            if output_keys[0] not in contract_sources:
                raise JSONError(f"outputSelection references unknown contract '{output_keys[0]}'")

        for key in output_keys:
            output_formats[key] = outputs

    return output_formats
Example #2
0
def compile_codes(contract_sources: ContractCodes,
                  output_formats: Union[OutputDict, OutputFormats,
                                        None] = None,
                  exc_handler: Union[Callable, None] = None,
                  interface_codes: Union[InterfaceDict, InterfaceImports,
                                         None] = None,
                  initial_id: int = 0) -> OrderedDict:

    if output_formats is None:
        output_formats = ('bytecode', )
    if isinstance(output_formats, Sequence):
        output_formats = dict(
            (k, output_formats) for k in contract_sources.keys())

    out: OrderedDict = OrderedDict()
    for source_id, contract_name in enumerate(sorted(contract_sources),
                                              start=initial_id):
        code = contract_sources[contract_name]
        for output_format in output_formats[contract_name]:
            if output_format not in OUTPUT_FORMATS:
                raise ValueError(
                    f'Unsupported format type {repr(output_format)}')

            try:
                interfaces: Any = interface_codes
                if (isinstance(interfaces, dict)
                        and contract_name in interfaces
                        and isinstance(interfaces[contract_name], dict)):
                    interfaces = interfaces[contract_name]
                out.setdefault(contract_name, {})
                out[contract_name][output_format] = OUTPUT_FORMATS[
                    output_format](
                        # trailing newline fixes python parsing bug when source ends in a comment
                        # https://bugs.python.org/issue35107
                        code=f"{code}\n",
                        contract_name=contract_name,
                        interface_codes=interfaces,
                        source_id=source_id)
            except Exception as exc:
                if exc_handler is not None:
                    exc_handler(contract_name, exc)
                else:
                    raise exc

    return out
Example #3
0
def compile_codes(contract_sources: ContractCodes,
                  output_formats: Union[OutputDict, OutputFormats,
                                        None] = None,
                  exc_handler: Union[Callable, None] = None,
                  interface_codes: Union[InterfaceDict, InterfaceImports,
                                         None] = None,
                  initial_id: int = 0) -> OrderedDict:

    if output_formats is None:
        output_formats = ('bytecode', )
    if isinstance(output_formats, Sequence):
        output_formats = dict(
            (k, output_formats) for k in contract_sources.keys())

    out: OrderedDict = OrderedDict()
    for source_id, contract_name in enumerate(sorted(contract_sources),
                                              start=initial_id):
        code = contract_sources[contract_name]
        for output_format in output_formats[contract_name]:
            if output_format not in output_formats_map:
                raise ValueError(
                    f'Unsupported format type {repr(output_format)}')

            try:
                interfaces: Any = interface_codes
                if (isinstance(interfaces, dict)
                        and contract_name in interfaces
                        and isinstance(interfaces[contract_name], dict)):
                    interfaces = interfaces[contract_name]
                out.setdefault(contract_name, {})
                out[contract_name][output_format] = output_formats_map[
                    output_format](code=code,
                                   contract_name=contract_name,
                                   interface_codes=interfaces,
                                   source_id=source_id)
            except Exception as exc:
                if exc_handler is not None:
                    exc_handler(contract_name, exc)
                else:
                    raise exc

    return out
Example #4
0
def compile_codes(
    contract_sources: ContractCodes,
    output_formats: Union[OutputDict, OutputFormats, None] = None,
    exc_handler: Union[Callable, None] = None,
    interface_codes: Union[InterfaceDict, InterfaceImports, None] = None,
    initial_id: int = 0,
) -> OrderedDict:
    """
    Generate compiler output(s) from one or more contract source codes.

    Arguments
    ---------
    contract_sources: Dict[str, str]
        Vyper source codes to be compiled. Formatted as `{"contract name": "source code"}`
    output_formats: List, optional
        List of compiler outputs to generate. Possible options are all the keys
        in `OUTPUT_FORMATS`. If not given, the deployment bytecode is generated.
    exc_handler: Callable, optional
        Callable used to handle exceptions if the compilation fails. Should accept
        two arguments - the name of the contract, and the exception that was raised
    initial_id: int, optional
        The lowest source ID value to be used when generating the source map.
    evm_version: str, optional
        The target EVM ruleset to compile for. If not given, defaults to the latest
        implemented ruleset.
    interface_codes: Dict, optional
        Interfaces that may be imported by the contracts during compilation.

        * May be a singular dictionary shared across all sources to be compiled,
          i.e. `{'interface name': "definition"}`
        * or may be organized according to contracts that are being compiled, i.e.
          `{'contract name': {'interface name': "definition"}`

        * Interface definitions are formatted as: `{'type': "json/vyper", 'code': "interface code"}`
        * JSON interfaces are given as lists, vyper interfaces as strings

    Returns
    -------
    Dict
        Compiler output as `{'contract name': {'output key': "output data"}}`
    """

    if output_formats is None:
        output_formats = ("bytecode", )
    if isinstance(output_formats, Sequence):
        output_formats = dict(
            (k, output_formats) for k in contract_sources.keys())

    out: OrderedDict = OrderedDict()
    for source_id, contract_name in enumerate(sorted(contract_sources),
                                              start=initial_id):
        # trailing newline fixes python parsing bug when source ends in a comment
        # https://bugs.python.org/issue35107
        source_code = f"{contract_sources[contract_name]}\n"
        interfaces: Any = interface_codes
        if (isinstance(interfaces, dict) and contract_name in interfaces
                and isinstance(interfaces[contract_name], dict)):
            interfaces = interfaces[contract_name]

        compiler_data = CompilerData(source_code, contract_name, interfaces,
                                     source_id)
        for output_format in output_formats[contract_name]:
            if output_format not in OUTPUT_FORMATS:
                raise ValueError(
                    f"Unsupported format type {repr(output_format)}")
            try:
                out.setdefault(contract_name, {})
                out[contract_name][output_format] = OUTPUT_FORMATS[
                    output_format](compiler_data)
            except Exception as exc:
                if exc_handler is not None:
                    exc_handler(contract_name, exc)
                else:
                    raise exc

    return out
Example #5
0
def compile_codes(
    contract_sources: ContractCodes,
    output_formats: Union[OutputDict, OutputFormats, None] = None,
    exc_handler: Union[Callable, None] = None,
    interface_codes: Union[InterfaceDict, InterfaceImports, None] = None,
    initial_id: int = 0,
    no_optimize: bool = False,
    storage_layouts: Dict[ContractPath, StorageLayout] = None,
    show_gas_estimates: bool = False,
) -> OrderedDict:
    """
    Generate compiler output(s) from one or more contract source codes.

    Arguments
    ---------
    contract_sources: Dict[str, str]
        Vyper source codes to be compiled. Formatted as `{"contract name": "source code"}`
    output_formats: List, optional
        List of compiler outputs to generate. Possible options are all the keys
        in `OUTPUT_FORMATS`. If not given, the deployment bytecode is generated.
    exc_handler: Callable, optional
        Callable used to handle exceptions if the compilation fails. Should accept
        two arguments - the name of the contract, and the exception that was raised
    initial_id: int, optional
        The lowest source ID value to be used when generating the source map.
    evm_version: str, optional
        The target EVM ruleset to compile for. If not given, defaults to the latest
        implemented ruleset.
    no_optimize: bool, optional
        Turn off optimizations. Defaults to False
    show_gas_estimates: bool, optional
        Show gas estimates for abi and ir output modes
    interface_codes: Dict, optional
        Interfaces that may be imported by the contracts during compilation.

        * May be a singular dictionary shared across all sources to be compiled,
          i.e. `{'interface name': "definition"}`
        * or may be organized according to contracts that are being compiled, i.e.
          `{'contract name': {'interface name': "definition"}`

        * Interface definitions are formatted as: `{'type': "json/vyper", 'code': "interface code"}`
        * JSON interfaces are given as lists, vyper interfaces as strings

    Returns
    -------
    Dict
        Compiler output as `{'contract name': {'output key': "output data"}}`
    """

    if output_formats is None:
        output_formats = ("bytecode", )
    if isinstance(output_formats, Sequence):
        output_formats = dict(
            (k, output_formats) for k in contract_sources.keys())

    out: OrderedDict = OrderedDict()
    for source_id, contract_name in enumerate(sorted(contract_sources),
                                              start=initial_id):
        source_code = contract_sources[contract_name]
        interfaces: Any = interface_codes
        storage_layout_override = None
        if storage_layouts and contract_name in storage_layouts:
            storage_layout_override = storage_layouts[contract_name]

        if (isinstance(interfaces, dict) and contract_name in interfaces
                and isinstance(interfaces[contract_name], dict)):
            interfaces = interfaces[contract_name]

        # make IR output the same between runs
        codegen.reset_names()
        compiler_data = CompilerData(
            source_code,
            contract_name,
            interfaces,
            source_id,
            no_optimize,
            storage_layout_override,
            show_gas_estimates,
        )
        for output_format in output_formats[contract_name]:
            if output_format not in OUTPUT_FORMATS:
                raise ValueError(
                    f"Unsupported format type {repr(output_format)}")
            try:
                out.setdefault(contract_name, {})
                out[contract_name][output_format] = OUTPUT_FORMATS[
                    output_format](compiler_data)
            except Exception as exc:
                if exc_handler is not None:
                    exc_handler(contract_name, exc)
                else:
                    raise exc

    return out