diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 55e45e321..c417ec0c2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -20,13 +20,16 @@ jobs: - uses: actions/checkout@v2 # v12 - uses: cachix/install-nix-action@v12 + with: + # https://discourse.nixos.org/t/understanding-binutils-darwin-wrapper-nix-support-bad-substitution/11475/2 + nix_path: nixpkgs=channel:nixos-unstable # v8 - uses: cachix/cachix-action@v8 with: name: dapp signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}' - name: run dapp tests - run: nix-shell --pure src/dapp-tests/shell.nix --command 'make --directory src/dapp-tests' + run: nix-shell --pure src/dapp-tests/shell.nix --command 'make ci --directory src/dapp-tests' - name: run hevm symbolic tests run: nix-build -j 1 -A hevm-tests - run: nix-collect-garbage diff --git a/src/dapp-tests/Makefile b/src/dapp-tests/Makefile index ad11312dc..5dce7df31 100644 --- a/src/dapp-tests/Makefile +++ b/src/dapp-tests/Makefile @@ -2,4 +2,8 @@ test: pytest --hypothesis-show-statistics integration/diff-fuzz.py bash_unit integration/tests.sh +ci: + pytest --hypothesis-show-statistics integration/diff-fuzz.py + FUZZ_RUNS=10000 TESTNET_SLEEP=90 bash_unit integration/tests.sh + .PHONY: test diff --git a/src/dapp-tests/integration/tests.sh b/src/dapp-tests/integration/tests.sh index 65441d63f..46041c265 100755 --- a/src/dapp-tests/integration/tests.sh +++ b/src/dapp-tests/integration/tests.sh @@ -1,13 +1,15 @@ #! /usr/bin/env bash -set -euo pipefail - # ------------------------------------------------ # CONFIGURATION # ------------------------------------------------ -FUZZ_RUNS=100 -TESTNET_SLEEP=5 +export SKIP_SETUP=${SKIP_SETUP:-0} +export FUZZ_RUNS=${FUZZ_RUNS:-100} +export TESTNET_SLEEP=${TESTNET_SLEEP:-5} +export RINKEBY_RPC_URL=${RINKEBY_RPC_URL:-https://rinkeby.infura.io/v3/84842078b09946638c03157f83405213} +export ARCHIVE_NODE_URL=${ARCHIVE_NODE_URL:-https://eth-mainnet.alchemyapi.io/v2/vpeKFsEF6PHifHzdtcwXSDbhV3ym5Ro4} +export ETHERSCAN_API_KEY=${ETHERSCAN_API_KEY:-15IS6MMRAYB19NZN9VHH6H6P57892Z664M} # ------------------------------------------------ # SHARED SETUP @@ -15,25 +17,26 @@ TESTNET_SLEEP=5 # we spin up a new testnet instance and share it between all tests setup_suite() { - if [[ -z "$SKIP_SETUP" ]]; then - TMPDIR=$(mktemp -d) + if [[ "$SKIP_SETUP" != 1 ]]; then + export GETHDIR + GETHDIR=$(mktemp -d) - dapp testnet --dir "$TMPDIR" & + dapp testnet --dir "$GETHDIR" & # give it a few secs to start up sleep "$TESTNET_SLEEP" export ETH_RPC_URL="http://127.0.0.1:8545" - export ETH_KEYSTORE="$TMPDIR/8545/keystore" + export ETH_KEYSTORE="$GETHDIR/8545/keystore" export ETH_PASSWORD=/dev/null - read -r ROOT _ <<< "$(seth ls --keystore "$TMPDIR/8545/keystore")" + read -r ROOT _ <<< "$(seth ls --keystore "$GETHDIR/8545/keystore")" fi } # cleanup the testnet teardown_suite() { - if [[ -z "$SKIP_SETUP" ]]; then + if [[ "$SKIP_SETUP" != 1 ]]; then killall geth - rm -rf "$TMPDIR" + rm -rf "$GETHDIR" fi } @@ -41,10 +44,6 @@ teardown_suite() { # TEST HELPERS # ------------------------------------------------ -# Tests for resolve-name and lookup-address use a Rinkeby name that's been registered for 100 years and will not be changed -# Infura ID source: https://github.com/ethers-io/ethers.js/blob/0d40156fcba5be155aa5def71bcdb95b9c11d889/packages/providers/src.ts/infura-provider.ts#L17 -RINKEBY_RPC_URL=https://rinkeby.infura.io/v3/84842078b09946638c03157f83405213 - # generates a new account and gives it some eth, returns the address fresh_account() { wei_amount=${1:-$(seth --to-wei 42069 ether)} @@ -115,43 +114,41 @@ alpha() { # `seth run-tx` # `hevm exec` test_smoke() { - local account + local account bytecode account=$(fresh_account) + bytecode=$(mktemp -d) # Deploy a simple contract: - solc --bin --bin-runtime "$CONTRACTS/stateful.sol" -o "$TMPDIR" + solc --bin --bin-runtime "$CONTRACTS/stateful.sol" -o "$bytecode" - A_ADDR=$(seth send --create "$(<"$TMPDIR"/A.bin)" "constructor(uint y)" 1 --from "$account" --keystore "$TMPDIR"/8545/keystore --password /dev/null --gas 0xffffff) + A_ADDR=$(seth send --create "$(<"$bytecode"/A.bin)" "constructor(uint y)" 1 --from "$account" --gas 0xffffff) # Compare deployed code with what solc gives us - assert_equals 0x"$(cat "$TMPDIR"/A.bin-runtime)" "$(seth code "$A_ADDR")" + assert_equals 0x"$(cat "$bytecode"/A.bin-runtime)" "$(seth code "$A_ADDR")" # And with what hevm gives us EXTRA_CALLDATA=$(seth --to-uint256 1) - HEVM_RET=$(hevm exec --code "$(<"$TMPDIR"/A.bin)""${EXTRA_CALLDATA/0x/}" --gas 0xffffff) + HEVM_RET=$(hevm exec --code "$(<"$bytecode"/A.bin)""${EXTRA_CALLDATA/0x/}" --gas 0xffffff) assert_equals "$HEVM_RET" "$(seth code "$A_ADDR")" - TX=$(seth send "$A_ADDR" "off()" --gas 0xffff --password /dev/null --from "$account" --keystore "$TMPDIR"/8545/keystore --async) + TX=$(seth send "$A_ADDR" "off()" --gas 0xffff --password /dev/null --from "$account" --async) # since we have one tx per block, seth run-tx and seth debug are equivalent - assert_equals 0x "$(seth run-tx "$TX")" + assert_equals 0x "$(seth run-tx "$TX" --no-src)" # dynamic fee transactions (EIP-1559) seth send "$A_ADDR" "on()" \ --gas 0xffff \ --password /dev/null \ --from "$account" \ - --keystore "$TMPDIR"/8545/keystore \ --prio-fee 2gwei \ --gas-price 10gwei - B_ADDR=$(seth send \ - --create 0x647175696e6550383480393834f3 \ + B_ADDR=$(seth send --create 0x647175696e6550383480393834f3 \ --gas 0xffff \ --password /dev/null \ - --from "$ACC" \ - --keystore "$TMPDIR"/8545/keystore \ + --from "$account" \ --prio-fee 2gwei \ --gas-price 10gwei) @@ -161,28 +158,28 @@ test_smoke() { # checks that seth send works with both checksummed and unchecksummed addresses test_seth_send_address_formats() { local account - account=$(fresh_account) + acc=$(fresh_account) - lower=$(echo "$account" | tr '[:upper:]' '[:lower:]') + lower=$(echo "$acc" | tr '[:upper:]' '[:lower:]') export ETH_GAS=0xffff # with checksummed - tx=$(seth send "$ZERO" --from "$ACC" --password /dev/null --value "$(seth --to-wei 1 ether)" --keystore "$TMPDIR"/8545/keystore --async) + tx=$(seth send "$ZERO" --from "$acc" --password /dev/null --value "$(seth --to-wei 1 ether)" --async) assert_equals "$lower" "$(seth tx "$tx" from)" # without checksum - tx=$(seth send "$ZERO" --from "$lower" --password /dev/null --value "$(seth --to-wei 1 ether)" --keystore "$TMPDIR"/8545/keystore --async) + tx=$(seth send "$ZERO" --from "$lower" --password /dev/null --value "$(seth --to-wei 1 ether)" --async) assert_equals "$lower" "$(seth tx "$tx" from)" # try again with eth_rpc_accounts export ETH_RPC_ACCOUNTS=true # with checksummed - tx=$(seth send "$ZERO" --from "$ACC" --password /dev/null --value "$(seth --to-wei 1 ether)" --keystore "$TMPDIR"/8545/keystore --async) + tx=$(seth send "$ZERO" --from "$acc" --password /dev/null --value "$(seth --to-wei 1 ether)" --async) assert_equals "$lower" "$(seth tx "$tx" from)" # without checksum - tx=$(seth send "$ZERO" --from "$lower" --password /dev/null --value "$(seth --to-wei 1 ether)" --keystore "$TMPDIR"/8545/keystore --async) + tx=$(seth send "$ZERO" --from "$lower" --password /dev/null --value "$(seth --to-wei 1 ether)" --async) assert_equals "$lower" "$(seth tx "$tx" from)" } @@ -192,27 +189,27 @@ test_hevm_symbolic() { solc --bin-runtime -o . --overwrite "$CONTRACTS/factor.sol" # should find counterexample - hevm symbolic --code "$( /dev/null || fail solc --bin-runtime -o . --overwrite "$CONTRACTS/token.sol" # This one explores all paths (cvc4 is better at this) - hevm symbolic --code "$( "$out" 2> "$err" + assert "grep -q 'Contract source code not verified' $err" 1 + assert "grep -q 'delegatecall 0xAa1c1B3BbbB59930a4E88F87345B8C513cc56Fa6::0x526327f2' $err" 2 + assert_equals "0x188fffa3a6cd08bdcc3d5bf4add2a2c0ac5e9d94a278ea1630187b3da583a1f0" "$(cat "$out")" + + local prefiles + prefiles=$(ls) + + # seth pulls from etherscan by default (flattened) + seth run-tx 0x41ccbab4d7d0cd55f481df7fce449986364bf13e655dddfb30aa9b38a4340db7 --trace 1> "$out" 2> "$err" + assert "grep -q 'UniswapV2Pair@0x28d2DF1E3481Ba90D75E14b9C02cea85b7d6FA2C' $err" 3 + assert "grep -q 'PairCreated(UniswapV2Pair@0x28d2DF1E3481Ba90D75E14b9C02cea85b7d6FA2C, 51691)' $err" 4 + assert_equals "0x00000000000000000000000028d2df1e3481ba90d75e14b9c02cea85b7d6fa2c" "$(cat "$out")" + + # seth does not write any files to the cwd + assert_equals "$prefiles" "$(ls)" + + # seth pulls from etherscan by default (stdjson) + seth run-tx 0x5da4bf1e5988cf94fd96d2c1dd3f420d2cea1aebe8d1e1c10dd9fe78a2147798 --trace 1> "$out" 2> "$err" + assert "grep -q 'ownerOf' $err" 5 + assert "grep -q 'iFeather@0xD1edDfcc4596CC8bD0bd7495beaB9B979fc50336' $err" 6 + assert_equals "0x" "$(cat "$out")" + + # seth does not write any files to the cwd + assert_equals "$prefiles" "$(ls)" + + # seth does not pull from etherscan if --source is passed + seth run-tx 0x41ccbab4d7d0cd55f481df7fce449986364bf13e655dddfb30aa9b38a4340db7 --trace --source /dev/null 1> "$out" 2> "$err" + assert "grep -q 'call 0x28d2DF1E3481Ba90D75E14b9C02cea85b7d6FA2C::0x485cc9550000000000000000000000007fa7df4' $err" 7 + assert "grep -q 'log3(0xd3648bd0f6ba80134a33ba9275ac585d9d315f0ad8355cddefde31afa28d0e9, 0xffffffffffffffff' $err" 8 + assert_equals "0x00000000000000000000000028d2df1e3481ba90d75e14b9c02cea85b7d6fa2c" "$(cat "$out")" + + # seth does not pull from etherscan if --no-src is passed at the command line + seth run-tx 0x41ccbab4d7d0cd55f481df7fce449986364bf13e655dddfb30aa9b38a4340db7 --trace --no-src 1> "$out" 2> "$err" + assert "grep -q 'call 0x28d2DF1E3481Ba90D75E14b9C02cea85b7d6FA2C::0x485cc9550000000000000000000000007fa7df4' $err" 9 + assert "grep -q 'log3(0xd3648bd0f6ba80134a33ba9275ac585d9d315f0ad8355cddefde31afa28d0e9, 0xffffffffffffffff' $err" 10 + assert_equals "0x00000000000000000000000028d2df1e3481ba90d75e14b9c02cea85b7d6fa2c" "$(cat "$out")" + + # seth does not pull from etherscan if SETH_NOSRC is set to "yes" + SETH_NOSRC=yes seth run-tx 0x41ccbab4d7d0cd55f481df7fce449986364bf13e655dddfb30aa9b38a4340db7 --trace 1> "$out" 2> "$err" + assert "grep -q 'call 0x28d2DF1E3481Ba90D75E14b9C02cea85b7d6FA2C::0x485cc9550000000000000000000000007fa7df4' $err" 11 + assert "grep -q 'log3(0xd3648bd0f6ba80134a33ba9275ac585d9d315f0ad8355cddefde31afa28d0e9, 0xffffffffffffffff' $err" 12 + assert_equals "0x00000000000000000000000028d2df1e3481ba90d75e14b9c02cea85b7d6fa2c" "$(cat "$out")" + + # seth does not pull from etherscan if ETHERSCAN_API_KEY is unset + unset ETHERSCAN_API_KEY + seth run-tx 0x41ccbab4d7d0cd55f481df7fce449986364bf13e655dddfb30aa9b38a4340db7 --trace 1> "$out" 2> "$err" + assert "grep -q 'call 0x28d2DF1E3481Ba90D75E14b9C02cea85b7d6FA2C::0x485cc9550000000000000000000000007fa7df4' $err" 13 + assert "grep -q 'log3(0xd3648bd0f6ba80134a33ba9275ac585d9d315f0ad8355cddefde31afa28d0e9, 0xffffffffffffffff' $err" 14 + assert_equals "0x00000000000000000000000028d2df1e3481ba90d75e14b9c02cea85b7d6fa2c" "$(cat "$out")" +} diff --git a/src/dapp-tests/shell.nix b/src/dapp-tests/shell.nix index dee3268db..3976d1d3d 100644 --- a/src/dapp-tests/shell.nix +++ b/src/dapp-tests/shell.nix @@ -14,5 +14,25 @@ in mkShell { name = "dapp-tests"; - buildInputs = [ killall bash_unit cacert bashInteractive curl dapp gnumake hevm procps seth solc go-ethereum python-with-pkgs ]; + buildInputs = [ + bashInteractive + bash_unit + bc + cacert + coreutils + curl + dapp + gnumake + go-ethereum + hevm + jq + killall + procps + python-with-pkgs + seth + solc + util-linux + which + ]; + LANG="en_US.UTF-8"; } diff --git a/src/dapp/CHANGELOG.md b/src/dapp/CHANGELOG.md index f562141ce..028873974 100644 --- a/src/dapp/CHANGELOG.md +++ b/src/dapp/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Added + +- The output from `dapp build` now uses color to differentiate warnings and errors + ### Changed - Dapp remappings ignores non-directories in `DAPP_LIB` diff --git a/src/dapp/libexec/dapp/dapp-build b/src/dapp/libexec/dapp/dapp-build index 2e9497067..4dbc52980 100755 --- a/src/dapp/libexec/dapp/dapp-build +++ b/src/dapp/libexec/dapp/dapp-build @@ -27,6 +27,13 @@ info() { echo >&2 "$FLAGS" "${0##*/}: $ARGS" } +colorize() { + awk '{ +gsub("Warning:", "\033[1;33m&\033[0m"); +gsub(".*Error:", "\033[1;31m&\033[0m"); +print }' +} + cd "$DAPP_ROOT" # use a custom path if DAPP_SOLC is set @@ -68,7 +75,7 @@ if [[ -z "$DAPP_BUILD_LEGACY" && -z "$DAPP_BUILD_EXTRACT" ]]; then # pipe errors to stderr jq -r 'if .errors then .errors | map(."formattedMessage") | @sh else empty end' "$DAPP_JSON" \ - | sed -e "s/' //g" -e "s/'//g" 1>&2 + | sed -e "s/' //g" -e "s/'//g" -e 's/\\\(.\)\\/\1 /g' | colorize 1>&2 # if sources is empty, the compilation failed [[ $(jq -r '.sources' "$DAPP_JSON") = "null" || $(jq -r '.sources' "$DAPP_JSON") = {} ]] && exit 1 || exit 0 diff --git a/src/hevm/src/EVM/Op.hs b/src/hevm/src/EVM/Op.hs index e46bad2e1..54e584735 100644 --- a/src/hevm/src/EVM/Op.hs +++ b/src/hevm/src/EVM/Op.hs @@ -167,4 +167,6 @@ opString (i, o) = let showPc x | x < 0x10 = '0' : showHex x "" OpLog x -> "LOG" ++ show x OpPush x -> "PUSH " ++ show x OpRevert -> "REVERT" - OpUnknown x -> "UNKNOWN " ++ show x + OpUnknown x -> case x of + 254 -> "INVALID" + _ -> "UNKNOWN " ++ (showHex x "") diff --git a/src/seth/CHANGELOG.md b/src/seth/CHANGELOG.md index 20928d91c..4b2ea6403 100644 --- a/src/seth/CHANGELOG.md +++ b/src/seth/CHANGELOG.md @@ -6,11 +6,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased -### Fixed - -- Contract creations with Dynamic fee transactions. -- `seth debug` correctly executes transactions. - ### Changed - `seth 4byte` command returns the response from querying [4byte.directory](https://www.4byte.directory/) for a given function signature @@ -19,10 +14,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `seth abi-encode` command returns the ABI encoded values without the function signature - `seth index` command returns the slot number for the specified mapping type and input data - `seth --from-fix` command converts fixed point numbers into parsed integers with the specified number of decimals +- `seth run-tx` now fetches contract source from etherscan if `ETHERSCAN_API_KEY` is set ### Fixed - Address lookup no longer fails if `ETH_RPC_ACCOUNTS` is set, and `ETH_FROM` is an unchecksummed address +- Contract creations with Dynamic fee transactions +- `seth debug` correctly executes transactions ## [0.11.0] - 2021-09-08 diff --git a/src/seth/README.md b/src/seth/README.md index c8744f320..7b6fcaf9c 100644 --- a/src/seth/README.md +++ b/src/seth/README.md @@ -560,6 +560,8 @@ provide source maps in calls to [`seth run-tx`] or [`hevm exec --debug --rpc`](. Requires the `ETHERSCAN_API_KEY` environment variable to be set. +Use `--dir` to control the directory in which compilation occurs (defaults to current working directory) + ### `seth call` Call a contract without updating the blockchain. @@ -802,16 +804,17 @@ so users must ensure the ENS names they enter are properly formatted. ### `seth run-tx` -Execute a transaction using `hevm`. +Run a transaction with hevm in the environment of the given transaction. seth run-tx [] +Attempts to fetch contract source from etherscan if `ETHERSCAN_API_KEY` is set. + With `--state dir`, load and save state from `dir` -With `--trace`, run in headless mode and print the call trace of the transaction. +With `--trace`, print the call trace of the transaction. With `--debug`, execute with hevm's interactive debugger -Use `--source=` to pass source information for a more illuminating experience. -Source files can be fetched remotely via [`seth bundle-source`], -but you can use the output of [`dapp build`](../dapp/README.md#dapp-build) here. +With `--no-src`, do not attempt to fetch contract source from etherscan +With `--source=`, manually supply a solc compiler output json (implies `--no-src`) ### `seth send` diff --git a/src/seth/libexec/seth/seth b/src/seth/libexec/seth/seth index ee569d842..4607ce68f 100755 --- a/src/seth/libexec/seth/seth +++ b/src/seth/libexec/seth/seth @@ -47,6 +47,7 @@ ### ### --debug run in hevm interactive mode ### --trace dump a trace to stderr +### --no-src don't try to fetch contract source ### --source= path to combined.json source ### --state= directory to store hevm state in ### diff --git a/src/seth/libexec/seth/seth-bundle-source b/src/seth/libexec/seth/seth-bundle-source index 9cb0f6a3c..a0b28fde1 100755 --- a/src/seth/libexec/seth/seth-bundle-source +++ b/src/seth/libexec/seth/seth-bundle-source @@ -4,6 +4,8 @@ ### ### Requires an etherscan api key ### +### Use `--dir` to control where the contract source is written (default is cwd) +### set -e [[ -z "$1" ]] && seth --fail-usage @@ -17,24 +19,26 @@ SOLC_VERSION=${SOLC_VERSION/+*} SOURCE="$(jq -r '.SourceCode' <<< "$ETHERSCAN_SRC" | tr -d '\r')" +SETH_DIR=${SETH_DIR:-.} + case "$SOURCE" in \{*\}) # standard-json # for some reason etherscan surrounds the actual json with '{}' SOURCE="${SOURCE/#\{\{/\{}" SOURCE="${SOURCE/%\}\}/\}}" - # write all source files in the local directory + # write all source files to SETH_DIR for x in $(echo "$SOURCE" | jq '.sources | keys | .[]' -r); do - mkdir -p "$(dirname "$x")" - echo "$SOURCE" | jq ".sources.\"$x\".content" -r > $x + mkdir -p "$SETH_DIR/$(dirname "$x")" + echo "$SOURCE" | jq ".sources.\"$x\".content" -r > "$SETH_DIR/$x" done; export DAPP_SOLC_JSON="$SOURCE" - seth --use solc:"${SOLC_VERSION}" solc + seth --use solc:"${SOLC_VERSION}" solc --dir "$SETH_DIR" ;; *) # flattened file NAME="$(jq -r '.ContractName' <<< "$ETHERSCAN_SRC")" - FILE="${SETH_DIR:-.}/${NAME}.sol" + FILE="$SETH_DIR/$NAME.sol" echo "$SOURCE" > "$FILE" OPT=$(jq -r '.OptimizationUsed' <<< "$ETHERSCAN_SRC") if [[ "$OPT" -ne 0 ]]; then diff --git a/src/seth/libexec/seth/seth-run-tx b/src/seth/libexec/seth/seth-run-tx index 68aab2d48..e3a1ade5b 100755 --- a/src/seth/libexec/seth/seth-run-tx +++ b/src/seth/libexec/seth/seth-run-tx @@ -5,9 +5,13 @@ ### ### Run a transaction with hevm in the environment of the given transaction. ### +### Attempts to fetch contract source from etherscan if `ETHERSCAN_API_KEY` is set. +### ### With `--state dir`, load and save state from `dir` ### With `--trace`, print the call trace of the transaction. ### With `--debug`, execute with hevm's interactive debugger +### With `--no-src`, do not attempt to fetch contract source from etherscan +### With `--source`, manually supply a solc compiler output json (implies --no-src) set -e # if the argument begins with 0x, we assume it to be a tx hash @@ -28,6 +32,12 @@ else opts+=(--address "$TO" --calldata "$DATA") fi +if [[ -n "$ETHERSCAN_API_KEY" && -z "$DAPP_JSON" && "$SETH_NOSRC" != yes ]]; then + TMP=$(mktemp -d) + DAPP_JSON="$TMP/solc.out.json" + seth bundle-source --dir "$TMP" "$TO" > "$DAPP_JSON" || : +fi + opts+=(--caller "$(<<< "$tx" seth --field from)" ) opts+=(--origin "$(<<< "$tx" seth --field from)") opts+=(--value "$(<<< "$tx" seth --field value)") @@ -44,4 +54,4 @@ opts+=(--chainid "${ETH_CHAINID:-$(seth rpc eth_chainId | seth --to-dec)}") [[ "$HEVM_TRACE" ]] && opts+=(--trace) [[ "$DAPP_JSON" ]] && opts+=(--json-file "$DAPP_JSON") -([[ $SETH_VERBOSE ]] && set -x; hevm exec "${opts[@]}") +([[ $SETH_VERBOSE ]] && set -x; [[ $DAPP_JSON ]] && cd "$TMP"; hevm exec "${opts[@]}") diff --git a/src/seth/libexec/seth/seth-solc b/src/seth/libexec/seth/seth-solc index 999826a7d..3a2eb7cca 100755 --- a/src/seth/libexec/seth/seth-solc +++ b/src/seth/libexec/seth/seth-solc @@ -8,11 +8,14 @@ ### - DAPP_SOLC_OPTIMIZE_RUNS (default 200) ### - DAPP_SOLC_JSON (must be provided if not specified) ### +### You can pass --dir to control the directory in which compilation will occur (default cwd) +### set -e OPTIMIZE=${DAPP_SOLC_OPTIMIZE:-false} RUNS=${DAPP_SOLC_OPTIMIZE_RUNS:-200} SOLC=${DAPP_SOLC:-solc} +SETH_DIR=${SETH_DIR:-.} if [[ -z "$DAPP_SOLC_JSON" && -z "$1" ]]; then seth --fail "must provide either .sol input file or DAPP_SOLC_JSON standard json" @@ -49,4 +52,4 @@ JSON="$(<<<"$JSON" jq '. ')" ( [[ $SETH_VERBOSE ]] && set -x; - echo "$JSON" | $SOLC --standard-json --allow-paths "$(realpath $1)" | jq . ) + cd "$SETH_DIR" && echo "$JSON" | $SOLC --standard-json --allow-paths "$(realpath "${1:-.}")" | jq . )