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
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
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
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
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