def test_environment_var_install(monkeypatch, tmp_path): assert not tmp_path.joinpath("solc-v0.6.9").exists() monkeypatch.setenv("SOLCX_BINARY_PATH", tmp_path.as_posix()) solcx.install_solc("0.6.9") assert tmp_path.joinpath("solc-v0.6.9").exists()
def compile_security_token(): install_solc("0.6.0") global abi, bytecode compiled_sol = compile_files( ["../../hardhat/contracts/SecurityToken.sol"], solc_version='0.6.0', optimize=True) print("compiled sources ") bytecode = compiled_sol['../../hardhat/contracts/SecurityToken.sol:SecurityToken']['bin'] abi = compiled_sol['../../hardhat/contracts/SecurityToken.sol:SecurityToken']['abi']
def set_solc_version(version): '''Sets the solc version. If not available it will be installed.''' try: solcx.set_solc_version(version) except solcx.exceptions.SolcNotInstalled: solcx.install_solc(version) solcx.set_solc_version(version) return solcx.get_solc_version_string().strip('\n')
def setup_compiler(self): try: solcx.set_solc_version(self.solc_version) except Exception as e: print("Solidity version " + self.solc_version + " does not exist in your system") print("Installing now ...") solcx.install_solc(self.solc_version) print("... OK")
def setup_solcx(solc_version): if solc_version not in solcx.get_installed_solc_versions(): try: LOGGER.debug(f"Installing solc {solc_version}") solcx.install_solc(solc_version, allow_osx=True) except Exception as e: raise click.exceptions.UsageError( f"Error installing solc version {solc_version}: {e}") solcx.set_solc_version(solc_version, silent=True)
def test_validate_installation_wrong_version(monkeypatch, install_mock, install_path): monkeypatch.setattr("solcx.wrapper._get_solc_version", lambda k: Version("0.0.0")) with pytest.raises(UnexpectedVersionError): solcx.install_solc() assert not install_path.exists()
def compile_contract(path, name): try : get_solc_version() except : install_solc(solc_version) print("install solc : {}".find(solc_version)) compiled_contacts = solcx.compile_files([path]) contract_interface = compiled_contacts['{}:{}'.format(path, name)] return contract_interface
def install_last_version(): try: install_solc() return True except (requests.exceptions.ConnectionError, subprocess.CalledProcessError) as e: print("Failed to install latest compiler. Trying to continue...") print("This might lead to later errors.") return False
def compile_solfiles(files, proj_dir, solc_version=None, output_values=OUTPUT_VALUES, remappings=None): def complete_remapping(remapping): name, old_path = remapping.split('=') new_path = os.path.join(proj_dir, old_path) return f'{name}={new_path}' if remappings is None: remappings = [] remappings = [complete_remapping(remapping) for remapping in remappings] node_modules_dir = find_node_modules_dir(proj_dir) if node_modules_dir is not None: zeppelin_path = os.path.abspath( os.path.join(node_modules_dir, 'zeppelin-solidity')) open_zeppelin_path = os.path.abspath( os.path.join(node_modules_dir, 'openzeppelin-solidity')) if os.path.isdir(zeppelin_path): remappings.append(f'zeppelin-solidity={zeppelin_path}') if os.path.isdir(open_zeppelin_path): remappings.append(f'openzeppelin-solidity={open_zeppelin_path}') if solc_version is None: if len(get_supported_solc_versions()) == 0: raise CompilerVersionNotSupported( "No compiler available. No connection to GitHub?") all_conditions = [] for source in files: all_conditions.extend(_parse_conditions(source)) solc_version = _find_version_for_conditions(all_conditions) try: install_solc(f'v{solc_version}') except (requests.exceptions.ConnectionError, subprocess.CalledProcessError): raise CompilerVersionNotSupported( f'Failed to install v{solc_version} compiler.') binary = _get_binary(solc_version) combined_json = ','.join(output_values) compiler_kwargs = { 'import_remappings': remappings, 'allow_paths': proj_dir, 'source_files': files, 'solc_binary': binary, 'combined_json': combined_json } try: stdoutdata, _, _, _ = solc_wrapper(**compiler_kwargs) return _parse_compiler_output(stdoutdata) except SolcError as e: raise SolidityCompilationException(e, solc_version, files)
def test_validate_installation_nightly(monkeypatch, install_mock, solc_binary, install_path): version = solcx.wrapper._get_solc_version(solc_binary) monkeypatch.setattr("solcx.wrapper._get_solc_version", lambda k: Version(f"{version}-nightly")) with pytest.warns(UnexpectedVersionWarning): solcx.install_solc() assert install_path.exists()
def install_solc(version: str) -> None: """Install the solidity compiler binary to the system for the specified version then set it as the default.""" try: from solcx import install_solc, set_solc_version except ImportError: error = f"Failed to install solc, py-solc-x is not found. " \ f"Install with 'pip install py-solc-x' and try again." raise ImportError(error) install_solc(version)
def _init_solc_binary(version: str) -> str: """ Only proper versions are supported. No nightlies, commits etc (such as available in remix). :param version: Version of the solc binary required :return: The solc binary of the corresponding version """ if not version: return os.environ.get("SOLC") or "solc" # tried converting input to semver, seemed not necessary so just slicing for now main_version = solc.main.get_solc_version_string() main_version_number = re.match(r"\d+.\d+.\d+", main_version) if main_version is None: raise CriticalError( "Could not extract solc version from string {}".format( main_version)) if version == main_version_number: log.info("Given version matches installed version") solc_binary = os.environ.get("SOLC") or "solc" else: solc_binary = util.solc_exists(version) if solc_binary and solc_binary != util.solc_exists( "default_ubuntu_version"): log.info("Given version is already installed") else: if version.startswith("0.4"): try: solc.install_solc("v" + version) except solc.exceptions.SolcError: raise CriticalError( "There was an error when trying to install the specified solc version" ) elif sys.version_info[1] >= 6: # solcx supports python 3.6+ try: solcx.install_solc("v" + version) except solcx.exceptions.SolcError: raise CriticalError( "There was an error when trying to install the specified solc version" ) else: raise CriticalError( "Py-Solc doesn't support 0.5.*. You can switch to python 3.6 which uses solcx." ) solc_binary = util.solc_exists(version) if not solc_binary: raise solc.exceptions.SolcError() log.info("Setting the compiler to %s", solc_binary) return solc_binary
def test_processlock(nosolc): # have to use a context here to prevent a conflict with tqdm ctx = mp.get_context("spawn") threads = [ ctx.Process(target=solcx.install_solc, args=("0.6.9", )) for i in range(4) ] for t in threads: t.start() solcx.install_solc("0.6.9") for t in threads: t.join() assert t.exitcode == 0
def all_versions(request): version = request.param if version not in _installed: try: solcx.install_solc(version) _installed[version] = True except Exception: _installed[version] = False pytest.fail(f"Unable to install solc {version}") if _installed[version]: solcx.set_solc_version(version) else: request.applymarker("skip")
def test_validate_installation_fails(monkeypatch, solc_binary, install_path): def _mock(*args, **kwargs): if sys.platform == "win32": install_path.mkdir() with install_path.joinpath("solc.exe").open("w") as fp: fp.write("blahblah") else: with install_path.open("w") as fp: fp.write("blahblah") monkeypatch.setattr("solcx.install._install_solc_unix", _mock) monkeypatch.setattr("solcx.install._install_solc_windows", _mock) with pytest.raises(SolcInstallationError): solcx.install_solc() assert not install_path.exists()
def pytest_collection(session): global VERSIONS if session.config.getoption("--solc-versions"): VERSIONS = [ Version(i) for i in session.config.getoption("--solc-versions").split(",") ] elif session.config.getoption("--no-install"): VERSIONS = solcx.get_installed_solc_versions() else: try: VERSIONS = solcx.get_installable_solc_versions() except ConnectionError: raise pytest.UsageError( "ConnectionError while attempting to get solc versions.\n" "Use the --no-install flag to only run tests against already installed versions." ) for version in VERSIONS: solcx.install_solc(version)
def compile(solc_version, evm_version, source_code_file): out = None source_code = "" with open(source_code_file, 'r') as file: source_code = file.read() try: if not str(solc_version).startswith("v"): solc_version = "v" + str(solc_version.truncate()) if not solc_version in solcx.get_installed_solc_versions(): solcx.install_solc(solc_version) solcx.set_solc_version(solc_version, True) out = solcx.compile_standard( { 'language': 'Solidity', 'sources': { source_code_file: { 'content': source_code } }, 'settings': { "optimizer": { "enabled": True, "runs": 200 }, "evmVersion": evm_version, "outputSelection": { source_code_file: { "*": [ "abi", "evm.deployedBytecode", "evm.bytecode.object", "evm.legacyAssembly", ], } } } }, allow_paths='.') except Exception as e: print("Error: Solidity compilation failed!") print(e.message) return out
def _compile_contract(self): install_solc('v0.6.2') set_solc_version('v0.6.2') ''' Compiles smart contract, creates bytecode and abi ''' # loading contract file data with open(tools.get_contr_path(), "r") as source_file: source_raw = source_file.read() # loading configuration data with open(tools.get_compile_data_path()) as opt_file: raw_opt = opt_file.read() opt = json.loads(raw_opt) #opt["sources"]["ResearchCertificate.sol"]["content"] = source_raw compiled_sol = compile_source(source_raw) contract_interface = compiled_sol['<stdin>:' + 'ResearchCertificate'] self.bytecode = contract_interface['bin'] self.abi = contract_interface['abi'] logging.info("Succesfully compiled contract")
def compiler(sol_file_name): with open('%s' % sol_file_name, 'r', encoding="utf-8") as sol_file: if_pragma = False while True: pragma_line = sol_file.readline() #print(pragma_line) pragma_pattern = r'(pragma)[\s]+(solidity)[\s]+(.+);[\s]*(/+.*)*' match_pragma_pattern = re.match(pragma_pattern, pragma_line) if match_pragma_pattern: pragmas = match_pragma_pattern.groups() pragma = pragmas[2] #print('pragma: %s' % pragma) install_solc_pragma(pragma) set_solc_version_pragma(pragma) if_pragma = True break if not pragma_line: break if not if_pragma: # no pragma install_solc('v0.4.25') set_solc_version('v0.4.25') compiled_sol = compile_files([sol_file_name]) file_name_key_list = list(compiled_sol.keys()) contract_name_list = list() for k in file_name_key_list: contract_name = k.split(':')[-1] contract_name_list.append(contract_name) with open('%s.bin.txt' % contract_name, 'w', encoding="utf-8") as outfile: json.dump(compiled_sol[k]['bin'], outfile, ensure_ascii=False) with open('%s.asm.json' % contract_name, 'w', encoding="utf-8") as outfile: json.dump(compiled_sol[k]['asm'], outfile, ensure_ascii=False) with open('ast.json', 'w', encoding="utf-8") as outfile: json.dump(compiled_sol[file_name_key_list[0]]['ast'], outfile, ensure_ascii=False) return (if_pragma, contract_name_list)
def _compile_contract(self): install_solc("v" + self.app_config.compiler_version) set_solc_version("v" + self.app_config.compiler_version) ''' Compiles smart contract, creates bytecode and abi ''' # loading contract file data with open(tools.get_contr_path(), "r") as source_file: source_raw = source_file.read() # loading configuration data with open(tools.get_compile_data_path()) as opt_file: raw_opt = opt_file.read() opt = json.loads(raw_opt) #opt["sources"]["ResearchCertificate.sol"]["content"] = source_raw #compiled_sol = compile_source(source_raw) compiled_sol = compile_files([tools.get_contr_path()], output_values=["abi", "bin"]) contract_interface = compiled_sol[tools.get_contr_path() + ":ResearchCertificate"] self.bytecode = contract_interface['bin'] self.abi = contract_interface['abi'] logging.info("Succesfully compiled contract")
def install_all_versions(): # First install last version if not install_last_version(): print("Failed to install all compiler. Trying to continue...") print("This might lead to later errors.") return False last_version = SolidityVersion(get_installed_solc_versions()[-1][1:]) next_version = MINIMAL_SOLC_VERSION while SolidityVersion(next_version) < last_version: try: install_solc(f'v{next_version}') # Increase major version new_minor = int(next_version.split(".")[2]) + 1 old_major = int(next_version.split(".")[1]) next_version = f'0.{old_major}.{new_minor}' except (requests.exceptions.ConnectionError, subprocess.CalledProcessError) as e: # Increase major version new_major = int(next_version.split(".")[1]) + 1 next_version = f'0.{new_major}.0'
def compile_source_file(file_path): """Read and compile the source file with the solc Solidity compiler. If the compiler is not available, it will be installed. """ # Check if solc compiler is available otherwise install try: print(solcx.get_solc_version()) except solcx.exceptions.SolcNotInstalled as e: print(e) version = solcx.install_solc('0.7.4') print(f'Installed version: {version}') with open(file_path, 'r') as f: source = f.read() return solcx.compile_source(source)
def install_solc(*versions: Union[Version, str]) -> None: """Installs solc versions.""" for version in versions: solcx.install_solc(version, show_progress=True)
def install_solc(*versions: str) -> None: """Installs solc versions.""" for version in versions: solcx.install_solc(str(version), show_progress=True)
def main(): version = get_solc_version() print(f"Fetched solc version {version} from source configuration") install_solc(version=version) print(f"Successfully installed solc {version}")
# -*- coding: utf-8 -*- """ proxy.py ~~~~~~~~ ⚡⚡⚡ Fast, Lightweight, Pluggable, TLS interception capable proxy server focused on Network monitoring, controls & Application development, testing, debugging. :copyright: (c) 2013-present by Abhinav Singh and contributors. :license: BSD, see LICENSE for more details. """ import sys sys.path.append( "/spl/bin/" ) # TODO: get rid off this workaround all related modules should either be installed as package or be linked from submodule from solcx import install_solc install_solc(version='0.7.6')
def install_sol() -> None: solcx.install_solc(SOL_COMPILER_VERSION)
# VYPER if contract_lang == 'vy': log('Compiling vyper contract!') abi = 'abi' byte = 'bytecode' # compile compiled_contract = compile_code(ctrct_src, [abi, byte]) # done log('Done compiling vyper contract.') # SOLIDITY elif contract_lang == 'sol': solc_version = "v" + ctrct_src.partition(' ^')[2].partition(';\n')[0] # version if not solc_version in get_installed_solc_versions(): log("Installing solc {}".format(solc_version)) install_solc(solc_version) log("Done.") set_solc_version(solc_version) # compile log('Compiling solidity {} contract!'.format(solc_version)) abi = 'abi' byte = 'bin' compiled_contract = compile_source(ctrct_src, output_values=[abi, byte]) # done log('Done compiling solidity contract.') compiled_contract = compiled_contract['<stdin>:{}'.format(contract_name)] # write with open("./data/abi/{}.abi".format(contract_name), "w") as file_abi: json.dump(compiled_contract[abi], file_abi) with open("./data/bin/{}.bin".format(contract_name), "w") as file_bin: file_bin.write(compiled_contract[byte])
def compile(self, contract_filepaths: List[Path], base_path: Optional[Path] = None) -> List[ContractType]: # TODO: move this to solcx contract_types = [] files = [] solc_version = None for path in contract_filepaths: files.append(path) source = path.read_text() pragma_spec = get_pragma_spec(source) # check if we need to install specified compiler version if pragma_spec: if pragma_spec is not pragma_spec.select( self.installed_versions): solc_version = pragma_spec.select(self.available_versions) if solc_version: solcx.install_solc(solc_version, show_progress=False) else: raise CompilerError( f"Solidity version '{solc_version}' is not available." ) else: solc_version = pragma_spec.select(self.installed_versions) else: solc_version = max(self.installed_versions) if not base_path: # Does support base_path from ape import config base_path = config.contracts_folder cli_base_path = base_path if solc_version >= Version("0.6.9") else None import_remappings = self.get_import_remapping(base_path=cli_base_path) kwargs = { "output_values": [ "abi", "bin", "bin-runtime", "devdoc", "userdoc", ], "solc_version": solc_version, "import_remappings": import_remappings, "optimize": self.config.optimize, } if cli_base_path: kwargs["base_path"] = cli_base_path output = solcx.compile_files(files, **kwargs) def load_dict(data: Union[str, dict]) -> Dict: return data if isinstance(data, dict) else json.loads(data) for contract_name, contract_type in output.items(): contract_id_parts = contract_name.split(":") contract_path = Path(contract_id_parts[0]) contract_type["contractName"] = contract_id_parts[-1] contract_type["sourceId"] = ( str(get_relative_path(base_path / contract_path, base_path)) if base_path and contract_path.is_absolute() else str(contract_path)) contract_type["deploymentBytecode"] = { "bytecode": contract_type["bin"] } contract_type["runtimeBytecode"] = { "bytecode": contract_type["bin-runtime"] } contract_type["userdoc"] = load_dict(contract_type["userdoc"]) contract_type["devdoc"] = load_dict(contract_type["devdoc"]) contract_types.append(ContractType.parse_obj(contract_type)) # Fix source IDs for when compiler did not account for base_path, # such as solidity<0.6.9. for contract_type in contract_types: if contract_type.source_id: source_id_path = Path(contract_type.source_id) if source_id_path.is_absolute(): contract_type.source_id = str( get_relative_path(source_id_path, base_path)) return contract_types
def generate_solidity_payload(file): """Generate a MythX analysis request from a given Solidity file. This function will open the file, try to detect the used solc version from the pragma definition, and automatically compile it. If the given solc version is not installed on the client's system, it will be automatically downloaded. From the solc output, the following data is sent to the MythX API for analysis: * :code:`abi` * :code:`ast` * :code:`bin` * :code:`bin-runtime` * :code:`srcmap` * :code:`srcmap-runtime` :param file: The path pointing towards the Solidity file :return: The payload dictionary to be sent to MythX """ with open(file) as f: source = f.read() solc_version = re.findall(PRAGMA_PATTERN, source) if not solc_version: # no pragma found, user needs to specify the version raise click.exceptions.UsageError( "No pragma found - please specify a solc version with --solc-version" ) # TODO: Pass user-defined version solc_version = "v" + solc_version[0] if solc_version not in solcx.get_installed_solc_versions(): try: solcx.install_solc(solc_version) except Exception as e: raise click.exceptions.UsageError( "Error installing solc version {}: {}".format(solc_version, e)) solcx.set_solc_version(solc_version, silent=True) try: result = solcx.compile_source( source, output_values=( "abi", "ast", "bin", "bin-runtime", "srcmap", "srcmap-runtime", ), ) except solcx.exceptions.SolcError as e: raise click.exceptions.UsageError( "Error compiling source with solc {}: {}".format(solc_version, e)) # sanitize weird solcx keys new_result = {} for key, value in result.items(): new_key = key.replace("<stdin>:", "") new_result[new_key] = value result = new_result contract_name = list(result.keys())[0] creation_bytecode = result[contract_name]["bin"] deployed_bytecode = result[contract_name]["bin-runtime"] source_map = result[contract_name]["srcmap"] deployed_source_map = result[contract_name]["srcmap-runtime"] ast = result[contract_name]["ast"] return { "contract_name": contract_name, "main_source": file, "source_list": [file], "sources": { file: { "source": source, "ast": ast } }, "bytecode": creation_bytecode, "source_map": source_map, "deployed_source_map": deployed_source_map, "deployed_bytecode": deployed_bytecode, "solc_version": solc_version, }