|
1 |
| -FROM ubuntu:focal |
2 |
| - |
3 |
| -ARG DEBIAN_FRONTEND=noninteractive |
4 |
| - |
5 |
| -# Space-separated version string without leading 'v' (e.g. "0.4.21 0.4.22") |
6 |
| -ARG SOLC |
7 |
| - |
8 |
| -RUN apt-get update \ |
9 |
| - && apt-get install -y \ |
10 |
| - libsqlite3-0 \ |
11 |
| - libsqlite3-dev \ |
12 |
| - && apt-get install -y \ |
13 |
| - apt-utils \ |
14 |
| - build-essential \ |
15 |
| - locales \ |
16 |
| - python-pip-whl \ |
17 |
| - python3-pip \ |
18 |
| - python3-setuptools \ |
19 |
| - software-properties-common \ |
20 |
| - && add-apt-repository -y ppa:ethereum/ethereum \ |
21 |
| - && apt-get update \ |
22 |
| - && apt-get install -y \ |
23 |
| - solc \ |
24 |
| - libssl-dev \ |
25 |
| - python3-dev \ |
26 |
| - pandoc \ |
27 |
| - git \ |
28 |
| - wget \ |
29 |
| - && ln -s /usr/bin/python3 /usr/local/bin/python |
30 |
| - |
31 |
| -COPY ./requirements.txt /opt/mythril/requirements.txt |
32 |
| - |
33 |
| -RUN cd /opt/mythril \ |
34 |
| - && pip3 install -r requirements.txt |
35 |
| - |
36 |
| -RUN locale-gen en_US.UTF-8 |
37 |
| -ENV LANG en_US.UTF-8 |
38 |
| -ENV LANGUAGE en_US.en |
39 |
| -ENV LC_ALL en_US.UTF-8 |
40 |
| - |
41 |
| -COPY . /opt/mythril |
42 |
| -RUN cd /opt/mythril \ |
43 |
| - && python setup.py install |
| 1 | +# syntax=docker/dockerfile:1 |
| 2 | +ARG PYTHON_VERSION=3.10 |
| 3 | +ARG INSTALLED_SOLC_VERSIONS |
44 | 4 |
|
| 5 | + |
| 6 | +FROM python:${PYTHON_VERSION:?} AS python-wheel |
| 7 | +WORKDIR /wheels |
| 8 | + |
| 9 | + |
| 10 | +FROM python-wheel AS python-wheel-with-cargo |
| 11 | +# Enable cargo sparse-registry to prevent it using large amounts of memory in |
| 12 | +# docker builds, and speed up builds by downloading less. |
| 13 | +# https://github.com/rust-lang/cargo/issues/10781#issuecomment-1163819998 |
| 14 | +ENV CARGO_UNSTABLE_SPARSE_REGISTRY=true |
| 15 | + |
| 16 | +RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y |
| 17 | +ENV PATH=/root/.cargo/bin:$PATH |
| 18 | + |
| 19 | + |
| 20 | +# z3-solver needs to build from src on arm, and it takes a long time, so |
| 21 | +# building it in a separate stage helps parallelise the build and helps it stay |
| 22 | +# in the build cache. |
| 23 | +FROM python-wheel AS python-wheel-z3-solver |
| 24 | +RUN pip install auditwheel |
| 25 | +RUN --mount=source=requirements.txt,target=/run/requirements.txt \ |
| 26 | + pip wheel "$(grep z3-solver /run/requirements.txt)" |
| 27 | +# The wheel z3-solver builds does not install in arm64 because it generates |
| 28 | +# incorrect platform compatibility metadata for arm64 builds. (It uses the |
| 29 | +# platform manylinux1_aarch64 but manylinux1 is only defined for x86 systems, |
| 30 | +# not arm: https://peps.python.org/pep-0600/#legacy-manylinux-tags). To work |
| 31 | +# around this, we use pypa's auditwheel tool to infer and apply a compatible |
| 32 | +# platform tag. |
| 33 | +RUN ( auditwheel addtag ./z3_solver-* \ |
| 34 | + # replace incorrect wheel with the re-tagged one |
| 35 | + && rm ./z3_solver-* && mv wheelhouse/z3_solver-* . ) \ |
| 36 | + # addtag exits with status 1 if no tags need adding, which is fine |
| 37 | + || true |
| 38 | + |
| 39 | + |
| 40 | +FROM python-wheel-with-cargo AS python-wheel-blake2b |
| 41 | +# blake2b-py doesn't publish ARM builds, and also don't publish source packages |
| 42 | +# on PyPI (other than the old 0.1.3 version) so we need to build from from a git |
| 43 | +# tag. They do publish binaries for linux amd64, but their binaries only support |
| 44 | +# certain platform versions and the amd64 python image isn't supported, so we |
| 45 | +# have to build from src for that as well. |
| 46 | + |
| 47 | +# Try to get a binary build or a source release on PyPI first, then fall back |
| 48 | +# to building from the git repo. |
| 49 | +RUN pip wheel 'blake2b-py>=0.2.0,<1' \ |
| 50 | + || pip wheel git+https://github.com/ethereum/ [email protected] |
| 51 | + |
| 52 | + |
| 53 | +FROM python-wheel AS mythril-wheels |
| 54 | +# cython is needed to build some wheels, such as cytoolz |
| 55 | +RUN pip install cython |
| 56 | +RUN --mount=source=requirements.txt,target=/run/requirements.txt \ |
| 57 | + # ignore blake2b and z3-solver as we've already built them |
| 58 | + grep -v -e blake2b -e z3-solver /run/requirements.txt > /tmp/requirements-remaining.txt |
| 59 | +RUN pip wheel -r /tmp/requirements-remaining.txt |
| 60 | + |
| 61 | +COPY . /mythril |
| 62 | +RUN pip wheel --no-deps /mythril |
| 63 | + |
| 64 | +COPY --from=python-wheel-blake2b /wheels/blake2b* /wheels |
| 65 | +COPY --from=python-wheel-z3-solver /wheels/z3_solver* /wheels |
| 66 | + |
| 67 | + |
| 68 | +# Solidity Compiler Version Manager. This provides cross-platform solc builds. |
| 69 | +# It's used by foundry to provide solc. https://github.com/roynalnaruto/svm-rs |
| 70 | +FROM python-wheel-with-cargo AS solidity-compiler-version-manager |
| 71 | +RUN cargo install svm-rs |
| 72 | +# put the binaries somewhere obvious for later stages to use |
| 73 | +RUN mkdir -p /svm-rs/bin && cd ~/.cargo/bin/ && cp svm solc /svm-rs/bin/ |
| 74 | + |
| 75 | + |
| 76 | +FROM python:${PYTHON_VERSION:?}-slim AS myth |
| 77 | +ARG PYTHON_VERSION |
| 78 | +# Space-separated version string without leading 'v' (e.g. "0.4.21 0.4.22") |
| 79 | +ARG INSTALLED_SOLC_VERSIONS |
| 80 | + |
| 81 | +COPY --from=solidity-compiler-version-manager /svm-rs/bin/* /usr/local/bin/ |
| 82 | + |
| 83 | +RUN --mount=from=mythril-wheels,source=/wheels,target=/wheels \ |
| 84 | + export PYTHONDONTWRITEBYTECODE=1 && pip install /wheels/*.whl |
| 85 | + |
| 86 | +RUN adduser --disabled-password mythril |
| 87 | +USER mythril |
45 | 88 | WORKDIR /home/mythril
|
46 | 89 |
|
47 |
| -RUN ( [ ! -z "${SOLC}" ] && set -e && for ver in $SOLC; do python -m solc.install v${ver}; done ) || true |
| 90 | +# pre-install solc versions |
| 91 | +RUN set -x; [ -z "${INSTALLED_SOLC_VERSIONS}" ] || svm install ${INSTALLED_SOLC_VERSIONS} |
| 92 | + |
| 93 | +COPY --chown=mythril:mythril \ |
| 94 | + ./mythril/support/assets/signatures.db \ |
| 95 | + /home/mythril/.mythril/signatures.db |
| 96 | + |
| 97 | +COPY --chown=root:root --chmod=755 ./docker/docker-entrypoint.sh / |
| 98 | +COPY --chown=root:root --chmod=755 \ |
| 99 | + ./docker/sync-svm-solc-versions-with-solcx.sh \ |
| 100 | + /usr/local/bin/sync-svm-solc-versions-with-solcx |
| 101 | +ENTRYPOINT ["/docker-entrypoint.sh"] |
| 102 | + |
| 103 | + |
| 104 | +# Basic sanity checks to make sure the build is functional |
| 105 | +FROM myth AS myth-smoke-test-execution |
| 106 | +SHELL ["/bin/bash", "-euo", "pipefail", "-c"] |
| 107 | +WORKDIR /smoke-test |
| 108 | +COPY --chmod=755 <<"EOT" /smoke-test.sh |
| 109 | +#!/usr/bin/env bash |
| 110 | +set -x -euo pipefail |
| 111 | + |
| 112 | +# Check solcx knows about svm solc versions |
| 113 | +svm install 0.5.0 |
| 114 | +sync-svm-solc-versions-with-solcx |
| 115 | +python -c ' |
| 116 | +import solcx |
| 117 | +print("\n".join(str(v) for v in solcx.get_installed_solc_versions())) |
| 118 | +' | grep -P '^0\.5\.0$' || { |
| 119 | + echo "solcx did not report svm-installed solc version"; |
| 120 | + exit 1 |
| 121 | +} |
| 122 | + |
| 123 | +# Check myth can run |
| 124 | +myth version |
| 125 | +myth function-to-hash 'function transfer(address _to, uint256 _value) public returns (bool success)' |
| 126 | +myth analyze /solidity_examples/timelock.sol > timelock.log || true |
| 127 | +grep 'SWC ID: 116' timelock.log || { |
| 128 | + error "Failed to detect SWC ID: 116 in timelock.sol"; |
| 129 | + exit 1 |
| 130 | +} |
| 131 | + |
| 132 | +# Check that the entrypoint works |
| 133 | +[[ $(/docker-entrypoint.sh version) == $(myth version) ]] |
| 134 | +[[ $(/docker-entrypoint.sh echo hi) == hi ]] |
| 135 | +[[ $(/docker-entrypoint.sh bash -c "printf '>%s<' 'foo bar'") == ">foo bar<" ]] |
| 136 | +EOT |
| 137 | + |
| 138 | +RUN --mount=source=./solidity_examples,target=/solidity_examples \ |
| 139 | + /smoke-test.sh 2>&1 | tee smoke-test.log |
48 | 140 |
|
49 |
| -COPY ./mythril/support/assets/signatures.db /home/mythril/.mythril/signatures.db |
50 | 141 |
|
51 |
| -ENTRYPOINT ["/usr/local/bin/myth"] |
| 142 | +FROM scratch as myth-smoke-test |
| 143 | +COPY --from=myth-smoke-test-execution /smoke-test/* / |
0 commit comments