Ejemplo n.º 1
0
def compileContract(file, lib=None, ldlib=None, file_path="Contracts"):
    file_path = getbase_dir(file_path)

    input_json = get_input_json(file_path, file, lib, ldlib)
    set_solc_version('v0.5.4')
    # return compile_files([file_path+file])
    return compile_standard(input_json, allow_paths=file_path)
Ejemplo n.º 2
0
def compile(solc_version, evm_version, source_code_file):
    out = None
    with open(source_code_file, 'r') as file:
        source_code = file.read()
        try:
            if solc_version != solcx.get_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
Ejemplo n.º 3
0
def compile_contract(path, name, contract_root):
    solcx.set_solc_version(SOLC_VERSION)
    compiled_contacts = solcx.compile_files([path],
                                            allow_paths=abspath(contract_root),
                                            optimize=True)
    contract_interface = compiled_contacts['{}:{}'.format(path, name)]
    return contract_interface
Ejemplo n.º 4
0
def compile_mixer() -> Interface:
    """
    Compile the testing mixer token contract
    """

    # zeth_dir = "/Users/ruanyang/works/snark-project/zeth/zeth/client"
    # print("***********", zeth_dir)
    # allowed_path = join(
    #     zeth_dir,
    #     "zeth_contracts/contracts")
    path_to_token = join(os.path.abspath('.'), "contract", "mixer",
                         "Groth16Mixer.sol")
    # Compilation
    set_solc_version(SOL_COMPILER_VERSION)
    compiled_sol = compile_files(
        [path_to_token], allow_paths=os.path.abspath('.').join("contract"))
    mixer_interface = compiled_sol[path_to_token + ":Groth16Mixer"]
    fo = open("./contract/mixer/abi/Groth16Mixer.abi", "w")
    fo0 = open("./contract/mixer/abi/Groth16Mixer1.abi", "w")
    fo1 = open("./contract/mixer/abi/Groth16Mixer.bin", "w")
    s1 = str(mixer_interface["abi"])
    origin = str(mixer_interface["abi"])
    s2 = s1.replace('True', 'true')
    s3 = s2.replace('False', 'false')
    s4 = s3.replace('\'', '\"')

    fo.write(s4)
    fo.close()
    fo0.write(origin)
    fo1.write(str(mixer_interface["bin"]))
    fo1.close()
Ejemplo n.º 5
0
def all_versions(request):
    """
    Run a test against all solc versions.
    """
    version = request.param
    solcx.set_solc_version(version)
    return version
Ejemplo n.º 6
0
 def __init__(self, config):
     if self.__validate(config):
         # Ethereum account address to interact with ethereum network
         self.__eth_account_address = config['ethereum']['eth_account']
         provider = config["ethereum"]["provider"]
         # Ethereum provider is endpoint to submit the transaction
         self.__w3 = web3.Web3(
             PROVIDER_DICT[urlparse(provider).scheme](provider))
         self._is_ropsten_provider = self._is_ropsten(provider)
         # Private key to sign the transaction
         if self._is_ropsten_provider:
             self.__eth_private_key = config['ethereum']['acc_pvt_key']
         # Chain id signifies the which ethereum network to use:
         # test net/main ethereum network
         self._chain_id = config["ethereum"]["chain_id"]
         # Maximum amount of gas you’re willing to spend on
         # a particular transaction
         self.__gas_limit = config["ethereum"]["gas_limit"]
         # Amount of Ether you’re willing to pay for every unit of gas
         self.__gas_price = config["ethereum"]["gas_price"]
         set_solc_version(config['ethereum']['solc_version'])
         logging.info("Solidity compiler version being used : {}".format(
             get_solc_version()))
     else:
         raise Exception("Invalid configuration parameter")
Ejemplo n.º 7
0
def compile_files(files: List[str], **kwargs: Any) -> Any:
    """
    Wrapper around solcx which ensures the required version of the compiler is
    used.
    """
    solcx.set_solc_version(SOL_COMPILER_VERSION)
    return solcx.compile_files(files, optimize=True, **kwargs)
Ejemplo n.º 8
0
    def __init__(
        self,
        web3,
        contract_to_deploy,
        contract_directory,
        max_deploy_gas = 5000000,
        max_tx_gas = 500000,
        deployment_vars_path = default_vars_path
        ):
        """Accepts contract, directory, and an RPC connection and sets defaults
        Parameters:
            web3 (Web3 object): the RPC node you'll make calls to (e.g. geth, ganache-cli)
            contract_to_deploy (str): name of the contract you want to interface with
            contract_directory (path): location of Solidity source files
            max_deploy_gas (int): max gas to use on deploy, see 'deploy_contract'
            max_tx_gas (int): max gas to use for transactions, see 'send'
            deployment_vars_path (path): default path for storing deployment variables
        Also sets web3.eth.defaultAccount as the coinbase account (e.g. the
        first key pair/account in ganache) for all send parameters
        """

        # SETUP solc version
        set_solc_version('v0.6.6')

        self.all_compiled_contracts = None
        self.web3 = web3
        self.contract_to_deploy = contract_to_deploy
        self.contract_directory = contract_directory
        self.max_deploy_gas = max_deploy_gas
        self.max_tx_gas = max_tx_gas
        self.deployment_vars_path = deployment_vars_path
Ejemplo n.º 9
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')
Ejemplo n.º 10
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)
Ejemplo n.º 11
0
 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")
Ejemplo n.º 12
0
def set_solc_version(version: str) -> str:
    """Sets the solc version. If not available it will be installed."""
    if Version(version.lstrip("v")) < Version("0.4.22"):
        raise IncompatibleSolcVersion("Brownie only supports Solidity versions >=0.4.22")
    try:
        solcx.set_solc_version(version, silent=True)
    except solcx.exceptions.SolcNotInstalled:
        install_solc(version)
        solcx.set_solc_version(version, silent=True)
    return str(solcx.get_solc_version())
Ejemplo n.º 13
0
def set_solc_version(version):
    '''Sets the solc version. If not available it will be installed.'''
    if Version(version.lstrip('v')) < Version('0.4.22'):
        raise IncompatibleSolcVersion(
            "Brownie only supports Solidity versions >=0.4.22")
    try:
        solcx.set_solc_version(version, silent=True)
    except solcx.exceptions.SolcNotInstalled:
        install_solc(version)
        solcx.set_solc_version(version, silent=True)
    return solcx.get_solc_version_string()
    def _compile_all_contracts(self) -> Dict:
        """
        Compile solidity contracts into ABI and BIN. This requires solc somewhere in the $PATH
        and also the :ref:`ethereum.tools` python library.  The return value is a dict that
        should be written into contracts.json.
        """
        solcx.install.install_solc(SOLC_VERSION)
        solcx.set_solc_version(SOLC_VERSION)
        ret = {}
        old_working_dir = Path.cwd()
        chdir(_BASE)

        def relativise(path: Path) -> Path:
            return path.relative_to(_BASE)

        import_dir_map = [
            "%s=%s" % (k, relativise(v))
            for k, v in self.contracts_source_dirs.items()
        ]
        import_dir_map.insert(
            0, ".=.")  # allow solc to compile contracts in all subdirs
        try:
            for contracts_dir in self.contracts_source_dirs.values():
                res = solcx.compile_files(
                    [
                        str(relativise(file))
                        for file in contracts_dir.glob("*.sol")
                    ],
                    output_values=PRECOMPILED_DATA_FIELDS + ["ast"],
                    import_remappings=import_dir_map,
                    optimize=False,
                )

                # Strip `ast` part from result
                # TODO: Remove after https://github.com/ethereum/py-solc/issues/56 is fixed
                res = {
                    contract_name: {
                        content_key: content_value
                        for content_key, content_value in
                        contract_content.items() if content_key != "ast"
                    }
                    for contract_name, contract_content in res.items()
                }
                ret.update(_fix_contract_key_names(res))
        except FileNotFoundError as ex:
            raise ContractSourceManagerCompilationError(
                "Could not compile the contract. Check that solc is available."
            ) from ex
        finally:
            chdir(old_working_dir)
        check_runtime_codesize(ret)
        return ret
Ejemplo n.º 15
0
def test_abi2solc(abi_path, version):
    if version == "0.4.17" and abi_path.parent.stem == "tuples":
        return
    abi = json.load(abi_path.open())
    solcx.set_solc_version(version)
    interface = abi2solc.generate_interface(abi, "Test", version.startswith("0.4"))
    generated_abi = solcx.compile_source(interface)["<stdin>:Test"]["abi"]
    if next((i for i in abi if i["type"] == "constructor"), False):
        assert len(abi) == len(generated_abi) + 1
    else:
        assert len(abi) == len(generated_abi)
    for item in generated_abi:
        assert item in abi
Ejemplo n.º 16
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")
Ejemplo n.º 17
0
def compile_mixer() -> Interface:
    allowed_path ="./contract/mixer"
    path_to_token = "./contract/mixer/Groth16Mixer.sol"
    # Compilation
    set_solc_version(SOL_COMPILER_VERSION)
    compiled_sol = compile_files([path_to_token], allow_paths=allowed_path)
    mixer_interface = compiled_sol[path_to_token + ":Groth16Mixer"]
    fo = open("./contract/mixer/abi/Groth16Mixer.abi", "w")
    fo1 = open("./contract/mixer/abi/Groth16Mixer.bin", "w")
    fo.write(str(mixer_interface["abi"]))
    fo.close()
    fo1.write(str(mixer_interface["bin"]))
    fo1.close()
    return mixer_interface
Ejemplo n.º 18
0
def compile_token() -> Interface:
    """
    Compile the testing ERC20 token contract
    """

    zeth_dir = get_zeth_dir()
    allowed_path = join(zeth_dir, "zeth_contracts/contracts")
    path_to_token = join(zeth_dir, "zeth_contracts/contracts",
                         "ERC20Mintable.sol")
    # Compilation
    set_solc_version(SOL_COMPILER_VERSION)
    compiled_sol = compile_files([path_to_token], allow_paths=allowed_path)
    token_interface = compiled_sol[path_to_token + ":ERC20Mintable"]
    return token_interface
Ejemplo n.º 19
0
def compile_token():

    zeth_dir = "/Users/ruanyang/works/snark-project/zk-client"
    print("***********", zeth_dir)
    allowed_path = join(zeth_dir, "contract")
    path_to_token = join(zeth_dir, "contract", "test1.sol")
    # Compilation
    set_solc_version(SOL_COMPILER_VERSION)
    compiled_sol = compile_files([path_to_token], allow_paths=allowed_path)
    token_interface = compiled_sol[path_to_token + ":Test1"]
    fo = open("./contract/Test1.abi", "w")
    fo1 = open("./contract/Test1.bin", "w")
    fo.write(str(token_interface["abi"]))
    fo.close()
    fo1.write(str(token_interface["bin"]))
    fo1.close()
Ejemplo n.º 20
0
def set_solc_version(version: Union[str, Version]) -> str:
    """Sets the solc version. If not available it will be installed."""
    if not isinstance(version, Version):
        version = Version(version.lstrip("v"))
    if version < Version("0.4.22"):
        raise IncompatibleSolcVersion("Brownie only supports Solidity versions >=0.4.22")
    try:
        solcx.set_solc_version(version, silent=True)
    except solcx.exceptions.SolcNotInstalled:
        if version not in _get_solc_version_list()[0]:
            raise IncompatibleSolcVersion(
                f"Cannot install Solidity v{version} on this OS. You may be able to "
                f"manually compile from source with `solcx.compile_solc('{version}')`"
            )
        install_solc(version)
        solcx.set_solc_version(version, silent=True)
    return str(solcx.get_solc_version())
Ejemplo n.º 21
0
def compile_mixer() -> Interface:
    """
    Compile the testing ERC20 token contract
    """

    zeth_dir = get_zeth_dir()
    print("***********", zeth_dir)
    allowed_path = join(
        zeth_dir,
        "zeth_contracts/node_modules/openzeppelin-solidity/contracts")
    path_to_token = join(
        zeth_dir,
        "zeth_contracts/node_modules/openzeppelin-solidity/contracts",
        "token/ERC20/ERC20Mintable.sol")
    # Compilation
    set_solc_version(SOL_COMPILER_VERSION)
    compiled_sol = compile_files([path_to_token], allow_paths=allowed_path)
    token_interface = compiled_sol[path_to_token + ":ERC20Mintable"]
    return token_interface
Ejemplo n.º 22
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")
Ejemplo n.º 23
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")
Ejemplo n.º 24
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)
    def generate_payloads(
        self,
        version: Optional[str],
        contract: str = None,
        remappings: Tuple[str] = None,
        enable_scribble: bool = False,
        scribble_path: str = "scribble",
    ):
        """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 version: The solc version to use for compilation
        :param contract: The contract name(s) to submit
        :param remappings: Import remappings to pass to solcx
        :param enable_scribble: Enable instrumentation with scribble
        :param scribble_path: Optional path to the scribble executable
        """

        with open(self.target) as f:
            source = f.read()

        solc_version = re.findall(PRAGMA_PATTERN, source)
        LOGGER.debug(f"solc version matches in {self.target}: {solc_version}")

        if not (solc_version or 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"
            )

        solc_version = f"v{version or solc_version[0]}"

        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)

        # instrument with scribble if requested
        scribble_file = None
        if enable_scribble:
            process = subprocess.run(
                [scribble_path, self.target],
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
            )
            if process.returncode != 0:
                click.echo(
                    f"Scribble has encountered an error (code: {process.returncode})"
                )
                click.echo("=====STDERR=====")
                click.echo(process.stderr.decode())
                click.echo("=====STDOUT=====")
                process.stdout.decode()
                sys.exit(process.returncode)

            # don't delete temp file on close but manually unlink
            # after payload has been generated
            scribble_output_f = tempfile.NamedTemporaryFile(mode="w+",
                                                            delete=False,
                                                            suffix=".sol")
            scribble_stdout = process.stdout.decode()
            scribble_output_f.write(scribble_stdout)
            scribble_file = scribble_output_f.name
            scribble_output_f.close()

        try:
            cwd = str(Path.cwd().absolute())
            LOGGER.debug(
                f"Compiling {scribble_file or self.target} under allowed path {cwd}"
            )
            result = solcx.compile_standard(
                input_data={
                    "language": "Solidity",
                    "sources": {
                        scribble_file or self.target: {
                            "urls": [scribble_file or self.target]
                        }
                    },
                    "settings": {
                        "remappings": [r.format(pwd=cwd) for r in remappings]
                        or [
                            f"openzeppelin-solidity/={cwd}/node_modules/openzeppelin-solidity/",
                            f"openzeppelin-zos/={cwd}/node_modules/openzeppelin-zos/",
                            f"zos-lib/={cwd}/node_modules/zos-lib/",
                        ],
                        "outputSelection": {
                            "*": {
                                "*": [
                                    "evm.bytecode.object",
                                    "evm.bytecode.sourceMap",
                                    "evm.deployedBytecode.object",
                                    "evm.deployedBytecode.sourceMap",
                                ],
                                "": ["ast"],
                            }
                        },
                        "optimizer": {
                            "enabled": True,
                            "runs": 200
                        },
                    },
                },
                # if scribble enabled, allow access to temporary file
                allow_paths=cwd if not enable_scribble else scribble_file,
            )
        except solcx.exceptions.SolcError as e:
            raise click.exceptions.UsageError(
                f"Error compiling source with solc {solc_version}: {e}")

        compiled_sources = result.get("sources", {})

        payload = {
            "sources": {},
            "solc_version": solc_version,
            "main_source": scribble_file or self.target,
            "source_list": [None] * len(compiled_sources),
        }

        for file_path, file_data in compiled_sources.items():
            # fill source list entry
            payload["source_list"][file_data.get("id")] = file_path
            payload_dict = payload["sources"][file_path] = {}

            # add AST for file if it's present
            ast = file_data.get("ast")
            if ast:
                payload_dict["ast"] = ast

            # add source from file path
            with open(file_path, newline="") as source_f:
                payload_dict["source"] = source_f.read()

        if contract:
            LOGGER.debug("Contract specified - targeted payload selection")
            try:
                # if contract specified, set its bytecode and source mapping
                payload["contract_name"] = contract
                payload["bytecode"] = patch_solc_bytecode(result["contracts"][
                    scribble_file
                    or self.target][contract]["evm"]["bytecode"]["object"])
                payload["source_map"] = result["contracts"][
                    scribble_file
                    or self.target][contract]["evm"]["bytecode"]["sourceMap"]
                payload["deployed_bytecode"] = patch_solc_bytecode(
                    result["contracts"][scribble_file or self.target][contract]
                    ["evm"]["deployedBytecode"]["object"])
                payload["deployed_source_map"] = result["contracts"][
                    scribble_file or self.
                    target][contract]["evm"]["deployedBytecode"]["sourceMap"]
                self.payloads.append(payload)
                return
            except KeyError:
                LOGGER.warning(
                    f"Could not find contract {contract} in compilation artifacts. The CLI will find the "
                    f"largest bytecode artifact in the compilation output and submit it instead."
                )

        # extract the largest bytecode from the compilation result and add it
        bytecode_max = 0
        for file_path, file_element in result.get("contracts", {}).items():
            for contract, contract_data in file_element.items():
                contract_bytecode = contract_data["evm"]["bytecode"]["object"]
                contract_source_map = contract_data["evm"]["bytecode"][
                    "sourceMap"]
                contract_deployed_bytecode = contract_data["evm"][
                    "deployedBytecode"]["object"]
                contract_deployed_source_map = contract_data["evm"][
                    "deployedBytecode"]["sourceMap"]
                bytecode_length = len(contract_bytecode)
                if bytecode_length > bytecode_max:
                    bytecode_max = bytecode_length
                    payload["contract_name"] = contract
                    payload["bytecode"] = patch_solc_bytecode(
                        contract_bytecode)
                    payload["source_map"] = contract_source_map
                    payload["deployed_bytecode"] = patch_solc_bytecode(
                        contract_deployed_bytecode)
                    payload[
                        "deployed_source_map"] = contract_deployed_source_map

        if enable_scribble:
            # replace scribble tempfile name with prefixed one
            scribble_payload = payload["sources"].pop(scribble_file)
            payload["sources"]["scribble-" +
                               str(self.target)] = scribble_payload
            payload["source_list"] = [
                "scribble-" +
                str(self.target) if item == scribble_file else item
                for item in payload["source_list"]
            ]
            payload["main_source"] = "scribble-" + str(self.target)

            # delete scribble temp file
            os.unlink(scribble_file)

        self.payloads.append(payload)
Ejemplo n.º 26
0
def generate_solidity_payload(
    file: str,
    version: Optional[str],
    contracts: List[str] = None,
    remappings: Tuple[str] = None,
) -> Dict:
    """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
    :param version: The solc version to use for compilation
    :param contracts: The contract name(s) to submit
    :param remappings: Import remappings to pass to solcx
    :return: The payload dictionary to be sent to MythX
    """

    with open(file) as f:
        solc_version = re.findall(PRAGMA_PATTERN, f.read())
    LOGGER.debug(f"solc version matches in {file}: {solc_version}")

    if not (solc_version or 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"
        )

    solc_version = f"v{version or solc_version[0]}"

    if solc_version not in solcx.get_installed_solc_versions():
        try:
            LOGGER.debug(f"Installing solc {solc_version}")
            solcx.install_solc(solc_version)
        except Exception as e:
            raise click.exceptions.UsageError(
                f"Error installing solc version {solc_version}: {e}")

    solcx.set_solc_version(solc_version, silent=True)
    try:
        cwd = str(Path.cwd().absolute())
        LOGGER.debug(f"Compiling {file} under allowed path {cwd}")
        result = solcx.compile_files(
            [file],
            output_values=(
                "abi",
                "ast",
                "bin",
                "bin-runtime",
                "srcmap",
                "srcmap-runtime",
            ),
            import_remappings=remappings or [
                f"openzeppelin-solidity/={cwd}/node_modules/openzeppelin-solidity/",
                f"openzeppelin-zos/={cwd}/node_modules/openzeppelin-zos/",
                f"zos-lib/={cwd}/node_modules/zos-lib/",
            ],
            allow_paths=cwd,
        )
    except solcx.exceptions.SolcError as e:
        raise click.exceptions.UsageError(
            f"Error compiling source with solc {solc_version}: {e}")

    # sanitize solcx keys
    new_result = {}
    for key, value in result.items():
        new_key = key.split(":")[1]
        LOGGER.debug(f"Sanitizing solc key {key} -> {new_key}")
        new_result[new_key] = value
    result = new_result

    payload = {"sources": {}, "solc_version": solc_version}

    bytecode_max = 0
    for contract_name, contract_data in result.items():
        ast = contract_data["ast"]
        source_path = str(Path(ast.get("attributes", {}).get("absolutePath")))
        creation_bytecode = contract_data["bin"]
        deployed_bytecode = contract_data["bin-runtime"]
        source_map = contract_data["srcmap"]
        deployed_source_map = contract_data["srcmap-runtime"]
        with open(source_path) as source_f:
            source = source_f.read()
            LOGGER.debug(
                f"Loaded contract source with {len(source)} characters")

        # always add source and AST, even if dependency
        payload["sources"][source_path] = {"source": source, "ast": ast}
        if (contracts and contract_name not in contracts) or (
                not contracts and len(creation_bytecode) < bytecode_max):
            LOGGER.debug(
                f"Found dependency contract {contract_name} - continung")
            continue

        bytecode_max = len(creation_bytecode)
        LOGGER.debug(f"Updaing main payload for {contract_name}")
        payload.update({
            "contract_name":
            contract_name,
            "main_source":
            source_path,
            "source_list": [source_path],
            "bytecode":
            patch_solc_bytecode(creation_bytecode),
            "source_map":
            zero_srcmap_indices(source_map),
            "deployed_source_map":
            zero_srcmap_indices(deployed_source_map),
            "deployed_bytecode":
            patch_solc_bytecode(deployed_bytecode),
            "solc_version":
            solc_version,
        })

    return payload
Ejemplo n.º 27
0
import os
import random
import re
from subprocess import CalledProcessError, check_call
import time
import socket
import threading
import jsonrpcclient.exceptions
import solcx
import web3

from test_framework.simple_rpc_proxy import SimpleRpcProxy
from . import coverage
from .authproxy import AuthServiceProxy, JSONRPCException

solcx.set_solc_version('v0.5.17')

CONFLUX_RPC_WAIT_TIMEOUT = 60
CONFLUX_GRACEFUL_SHUTDOWN_TIMEOUT = 1220

logger = logging.getLogger("TestFramework.utils")

# Assert functions
##################


def assert_fee_amount(fee, tx_size, fee_per_kB):
    """Assert the fee was in range"""
    target_fee = round(tx_size * fee_per_kB / 1000, 8)
    if fee < target_fee:
        raise AssertionError("Fee of %s BTC too low! (Should be %s BTC)" %
Ejemplo n.º 28
0
#!/usr/bin/python3
# -*- coding: utf-8 -*-

from solcx import compile_source, set_solc_version

set_solc_version("v0.5.16")

with open('contracts/VotacionElecciones.sol', 'r') as content:
    CODIGO = content.read()

COMPILACION = list(compile_source(CODIGO).values())[0]

ABI = COMPILACION['abi']
ASM = COMPILACION['asm']
BYTECODE = COMPILACION['bin']
RUNTIME = COMPILACION['bin-runtime']
OPCODES = COMPILACION['opcodes']
AST = COMPILACION['ast']
Ejemplo n.º 29
0
        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])

#######################
Ejemplo n.º 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,
    }