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']
示例#3
0
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")
示例#5
0
 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()
示例#7
0
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
示例#8
0
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
示例#9
0
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()
示例#11
0
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)
示例#12
0
    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
示例#13
0
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
示例#14
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()
示例#16
0
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)
示例#17
0
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
示例#18
0
    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")
示例#19
0
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)
示例#20
0
    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")
示例#21
0
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'
示例#22
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)
示例#23
0
def install_solc(*versions: Union[Version, str]) -> None:
    """Installs solc versions."""
    for version in versions:
        solcx.install_solc(version, show_progress=True)
示例#24
0
def install_solc(*versions: str) -> None:
    """Installs solc versions."""
    for version in versions:
        solcx.install_solc(str(version), show_progress=True)
示例#25
0
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}")
示例#26
0
# -*- 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')
示例#27
0
def install_sol() -> None:
    solcx.install_solc(SOL_COMPILER_VERSION)
示例#28
0
 # 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])
示例#29
0
    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
示例#30
0
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,
    }