Py35 support (#1233)

* Add py35 into tox

* Use solcx for python3.6+

* Fix tests
pull/1246/head
Nikhil Parasaram 5 years ago committed by GitHub
parent 07347e28ff
commit 7a105e5dec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      mythril/ethereum/util.py
  2. 24
      mythril/mythril/mythril_disassembler.py
  3. 10
      tests/laser/transaction/create_transaction_test.py
  4. 5
      tests/native_test.py
  5. 16
      tests/solidity_contract_test.py
  6. 2
      tox.ini

@ -2,8 +2,8 @@
solc integration.""" solc integration."""
import binascii import binascii
import json import json
import sys
import os import os
import solcx
from pathlib import Path from pathlib import Path
from subprocess import PIPE, Popen from subprocess import PIPE, Popen
@ -12,6 +12,9 @@ from ethereum.utils import zpad
from mythril.exceptions import CompilerError from mythril.exceptions import CompilerError
if sys.version_info[1] >= 6:
import solcx
def safe_decode(hex_encoded_string): def safe_decode(hex_encoded_string):
""" """
@ -128,10 +131,9 @@ def solc_exists(version):
"bin/solc", "bin/solc",
) # py-solc setup ) # py-solc setup
] ]
else: elif sys.version_info[1] >= 6:
# we are using solc-x for the the 0.5 and higher # we are using solc-x for the the 0.5 and higher
solc_binaries = [os.path.join(solcx.__path__[0], "bin", "solc-v" + version)] solc_binaries = [os.path.join(solcx.__path__[0], "bin", "solc-v" + version)]
for solc_path in solc_binaries: for solc_path in solc_binaries:
if os.path.exists(solc_path): if os.path.exists(solc_path):
return solc_path return solc_path

@ -1,7 +1,7 @@
import logging import logging
import re import re
import solc import solc
import solcx import sys
import os import os
from ethereum import utils from ethereum import utils
@ -14,6 +14,9 @@ from mythril.ethereum.evmcontract import EVMContract
from mythril.ethereum.interface.rpc.exceptions import ConnectionError from mythril.ethereum.interface.rpc.exceptions import ConnectionError
from mythril.solidity.soliditycontract import SolidityContract, get_contracts_from_file from mythril.solidity.soliditycontract import SolidityContract, get_contracts_from_file
if sys.version_info[1] >= 6:
import solcx
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -67,22 +70,29 @@ class MythrilDisassembler:
): ):
log.info("Given version is already installed") log.info("Given version is already installed")
else: else:
try:
if version.startswith("0.4"): if version.startswith("0.4"):
try:
solc.install_solc("v" + version) solc.install_solc("v" + version)
else:
solcx.install_solc("v" + version)
solc_binary = util.solc_exists(version)
if not solc_binary:
raise solc.exceptions.SolcError()
except solc.exceptions.SolcError: except solc.exceptions.SolcError:
raise CriticalError( raise CriticalError(
"There was an error when trying to install the specified solc version" "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: except solcx.exceptions.SolcError:
raise CriticalError( raise CriticalError(
"There was an error when trying to install the specified solc version" "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) log.info("Setting the compiler to %s", solc_binary)

@ -11,10 +11,7 @@ from mythril.analysis.symbolic import SymExecWrapper
def test_create(): def test_create():
contract = SolidityContract( contract = SolidityContract(str(tests.TESTDATA_INPUTS_CONTRACTS / "calls.sol"))
str(tests.TESTDATA_INPUTS_CONTRACTS / "calls.sol"),
solc_binary=MythrilDisassembler._init_solc_binary("0.5.0"),
)
laser_evm = svm.LaserEVM({}) laser_evm = svm.LaserEVM({})
@ -35,10 +32,7 @@ def test_create():
def test_sym_exec(): def test_sym_exec():
contract = SolidityContract( contract = SolidityContract(str(tests.TESTDATA_INPUTS_CONTRACTS / "calls.sol"))
str(tests.TESTDATA_INPUTS_CONTRACTS / "calls.sol"),
solc_binary=MythrilDisassembler._init_solc_binary("0.5.0"),
)
sym = SymExecWrapper( sym = SymExecWrapper(
contract, contract,

@ -78,10 +78,7 @@ class NativeTests(BaseTestCase):
"""""" """"""
# The solidity version (0.5.3 at the moment) should be kept in sync with # The solidity version (0.5.3 at the moment) should be kept in sync with
# pragma in ./tests/native_tests.sol # pragma in ./tests/native_tests.sol
disassembly = SolidityContract( disassembly = SolidityContract("./tests/native_tests.sol").disassembly
"./tests/native_tests.sol",
solc_binary=MythrilDisassembler._init_solc_binary("0.5.3"),
).disassembly
account = Account("0x0000000000000000000000000000000000000000", disassembly) account = Account("0x0000000000000000000000000000000000000000", disassembly)
world_state = WorldState() world_state = WorldState()
world_state.put_account(account) world_state.put_account(account)

@ -10,9 +10,7 @@ TEST_FILES = Path(__file__).parent / "testdata/input_contracts"
class SolidityContractTest(BaseTestCase): class SolidityContractTest(BaseTestCase):
def test_get_source_info_without_name_gets_latest_contract_info(self): def test_get_source_info_without_name_gets_latest_contract_info(self):
input_file = TEST_FILES / "multi_contracts.sol" input_file = TEST_FILES / "multi_contracts.sol"
contract = SolidityContract( contract = SolidityContract(str(input_file))
str(input_file), solc_binary=MythrilDisassembler._init_solc_binary("0.5.0")
)
code_info = contract.get_source_info(142) code_info = contract.get_source_info(142)
@ -22,11 +20,7 @@ class SolidityContractTest(BaseTestCase):
def test_get_source_info_with_contract_name_specified(self): def test_get_source_info_with_contract_name_specified(self):
input_file = TEST_FILES / "multi_contracts.sol" input_file = TEST_FILES / "multi_contracts.sol"
contract = SolidityContract( contract = SolidityContract(str(input_file), name="Transfer1")
str(input_file),
name="Transfer1",
solc_binary=MythrilDisassembler._init_solc_binary("0.5.0"),
)
code_info = contract.get_source_info(142) code_info = contract.get_source_info(142)
@ -36,11 +30,7 @@ class SolidityContractTest(BaseTestCase):
def test_get_source_info_with_contract_name_specified_constructor(self): def test_get_source_info_with_contract_name_specified_constructor(self):
input_file = TEST_FILES / "constructor_assert.sol" input_file = TEST_FILES / "constructor_assert.sol"
contract = SolidityContract( contract = SolidityContract(str(input_file), name="AssertFail")
str(input_file),
name="AssertFail",
solc_binary=MythrilDisassembler._init_solc_binary("0.5.0"),
)
code_info = contract.get_source_info(70, constructor=True) code_info = contract.get_source_info(70, constructor=True)

@ -1,5 +1,5 @@
[tox] [tox]
envlist = py36 envlist = py35, py36
[testenv] [testenv]
deps = deps =

Loading…
Cancel
Save