From 20103cec0eccef0c8000fef58e5b6ac32f90a877 Mon Sep 17 00:00:00 2001 From: Nazzareno Massari Date: Mon, 29 Mar 2021 20:03:45 +0100 Subject: [PATCH 01/24] add --multiple opt to dapp-verify-contract --- src/dapp/libexec/dapp/dapp-verify-contract | 87 +++++++++++++++------- 1 file changed, 60 insertions(+), 27 deletions(-) diff --git a/src/dapp/libexec/dapp/dapp-verify-contract b/src/dapp/libexec/dapp/dapp-verify-contract index edd3f7df5..99d0b285a 100755 --- a/src/dapp/libexec/dapp/dapp-verify-contract +++ b/src/dapp/libexec/dapp/dapp-verify-contract @@ -1,17 +1,15 @@ #!/usr/bin/env bash ### dapp-verify-contract -- verify contract souce on etherscan ### Usage: dapp verify-contract :
[constructorArgs] +### Option: --multiple for standard-json multi-file verification set -e [[ $ETHERSCAN_API_KEY ]] || { cat >&2 <<. - You need an Etherscan Api Key to verify contracts. Create one at https://etherscan.io/myapikey - Then export it with \`export ETHERSCAN_API_KEY=xxxxxxxx' - . exit 1 } @@ -41,7 +39,7 @@ address=${2?contractaddress} # combined-json has a sourceList field if [[ $(jq .sourceList "$DAPP_JSON") == null ]]; then contract=$(<"$DAPP_JSON" jq -r ".contracts[\"${path/:*/}\"][\"$name\"]") -else +else contract=$(<"$DAPP_JSON" jq -r ".contracts[\"$path\"]") fi meta=$(jshon <<<"$contract" -e metadata -u) @@ -88,41 +86,76 @@ else optimized=0 fi -params=( +if [[ $1 = "--multiple" ]]; then + + # Standard Input JSON + inputJSON=$(dapp mk-standard-json) + + params=( "module=contract" "action=verifysourcecode" "contractname=$name" "contractaddress=$address" + "sourcecode=$inputJSON" "codeformat=solidity-standard-json-input" "optimizationUsed=$optimized" "runs=$runs" "apikey=$ETHERSCAN_API_KEY" -) + ) -source=$(hevm flatten --source-file "$file" --json-file "$DAPP_JSON" --dapp-root "$DAPP_ROOT") + query=$(printf "&%s" "${params[@]}") -source=$(cat <<. -// Verified using https://dapp.tools + count=0 + while [ $count -lt 5 ]; do + sleep 10 -$source -. -) + response=$(curl -fsS "$ETHERSCAN_API_URL" -d "$query" \ + --data-urlencode "compilerversion=$version" \ + --data-urlencode "constructorArguements=$constructorArguments" -X POST) + # NOTE: the Arguements typo is in etherscan's API + + status=$(jshon <<<"$response" -e status -u) + guid=$(jshon <<<"$response" -e result -u) + message=$(jshon <<<"$response" -e message -u) + count=$((count + 1)) -query=$(printf "&%s" "${params[@]}") + [[ $status = 1 ]] && break; + done -count=0 -while [ $count -lt 5 ]; do - sleep 10 +else + + params=( + "module=contract" "action=verifysourcecode" + "contractname=$name" "contractaddress=$address" + "optimizationUsed=$optimized" "runs=$runs" + "apikey=$ETHERSCAN_API_KEY" + ) + + source=$(hevm flatten --source-file "$file" --json-file "$DAPP_JSON" --dapp-root "$DAPP_ROOT") + + source=$(cat <<. + // Verified using https://dapp.tools + $source + . + ) - response=$(curl -fsS "$ETHERSCAN_API_URL" -d "$query" \ - --data-urlencode "compilerversion=$version" \ - --data-urlencode "sourceCode@"<(echo "$source") \ - --data-urlencode "constructorArguements=$constructorArguments" -X POST) - # NOTE: the Arguements typo is in etherscan's API + query=$(printf "&%s" "${params[@]}") - status=$(jshon <<<"$response" -e status -u) - guid=$(jshon <<<"$response" -e result -u) - message=$(jshon <<<"$response" -e message -u) - count=$((count + 1)) + count=0 + while [ $count -lt 5 ]; do + sleep 10 - [[ $status = 1 ]] && break; -done + response=$(curl -fsS "$ETHERSCAN_API_URL" -d "$query" \ + --data-urlencode "compilerversion=$version" \ + --data-urlencode "sourceCode@"<(echo "$source") \ + --data-urlencode "constructorArguements=$constructorArguments" -X POST) + # NOTE: the Arguements typo is in etherscan's API + + status=$(jshon <<<"$response" -e status -u) + guid=$(jshon <<<"$response" -e result -u) + message=$(jshon <<<"$response" -e message -u) + count=$((count + 1)) + + [[ $status = 1 ]] && break; + done + +fi [[ $status = 0 && $message = "Contract source code already verified" ]] && { echo >&2 "Contract source code already verified." From 9ae6abffc14560df853b504d4daefd53b164a371 Mon Sep 17 00:00:00 2001 From: Nazzareno Massari Date: Mon, 29 Mar 2021 22:27:53 +0100 Subject: [PATCH 02/24] shellcheck fix --- src/dapp/libexec/dapp/dapp-verify-contract | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/dapp/libexec/dapp/dapp-verify-contract b/src/dapp/libexec/dapp/dapp-verify-contract index 99d0b285a..484ed653d 100755 --- a/src/dapp/libexec/dapp/dapp-verify-contract +++ b/src/dapp/libexec/dapp/dapp-verify-contract @@ -129,11 +129,7 @@ else source=$(hevm flatten --source-file "$file" --json-file "$DAPP_JSON" --dapp-root "$DAPP_ROOT") - source=$(cat <<. - // Verified using https://dapp.tools - $source - . - ) + source=$(cat <<<. //Verified using https://dapp.tools "$source".) query=$(printf "&%s" "${params[@]}") From a10c011ee7c5c2b512340550a20ba497a893de5c Mon Sep 17 00:00:00 2001 From: Nazzareno Massari Date: Tue, 30 Mar 2021 00:06:32 +0100 Subject: [PATCH 03/24] cleanup --- src/dapp/libexec/dapp/dapp-verify-contract | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/dapp/libexec/dapp/dapp-verify-contract b/src/dapp/libexec/dapp/dapp-verify-contract index 484ed653d..1068aaf88 100755 --- a/src/dapp/libexec/dapp/dapp-verify-contract +++ b/src/dapp/libexec/dapp/dapp-verify-contract @@ -129,7 +129,11 @@ else source=$(hevm flatten --source-file "$file" --json-file "$DAPP_JSON" --dapp-root "$DAPP_ROOT") - source=$(cat <<<. //Verified using https://dapp.tools "$source".) + source=$(cat <<. + //Verified using https://dapp.tools + "$source" +. + ) query=$(printf "&%s" "${params[@]}") From 12d0725187fffaf84cee932f502283e0faae3ca2 Mon Sep 17 00:00:00 2001 From: Nazzareno Massari Date: Thu, 1 Apr 2021 22:20:52 +0100 Subject: [PATCH 04/24] add contractName as contractfile.sol:contractname format --- src/dapp/libexec/dapp/dapp-verify-contract | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/dapp/libexec/dapp/dapp-verify-contract b/src/dapp/libexec/dapp/dapp-verify-contract index 1068aaf88..b24c131ca 100755 --- a/src/dapp/libexec/dapp/dapp-verify-contract +++ b/src/dapp/libexec/dapp/dapp-verify-contract @@ -34,6 +34,7 @@ esac path=${1?contractname} name=${path#*:} +contractName=$(basename $path) address=${2?contractaddress} # combined-json has a sourceList field @@ -93,7 +94,7 @@ if [[ $1 = "--multiple" ]]; then params=( "module=contract" "action=verifysourcecode" - "contractname=$name" "contractaddress=$address" + "contractname=$contractName" "contractaddress=$address" "sourcecode=$inputJSON" "codeformat=solidity-standard-json-input" "optimizationUsed=$optimized" "runs=$runs" "apikey=$ETHERSCAN_API_KEY" From def7e5e1951c47d63546434c91bbbfd747ff81dd Mon Sep 17 00:00:00 2001 From: Nazzareno Massari Date: Thu, 1 Apr 2021 22:21:53 +0100 Subject: [PATCH 05/24] shellcheck fix --- src/dapp/libexec/dapp/dapp-verify-contract | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dapp/libexec/dapp/dapp-verify-contract b/src/dapp/libexec/dapp/dapp-verify-contract index b24c131ca..84773c33f 100755 --- a/src/dapp/libexec/dapp/dapp-verify-contract +++ b/src/dapp/libexec/dapp/dapp-verify-contract @@ -34,7 +34,7 @@ esac path=${1?contractname} name=${path#*:} -contractName=$(basename $path) +contractName=$(basename "$path") address=${2?contractaddress} # combined-json has a sourceList field From 948b559a3e168242f4ea8115f6326d2bb2c71fc9 Mon Sep 17 00:00:00 2001 From: Nazzareno Massari Date: Tue, 6 Apr 2021 17:07:22 +0100 Subject: [PATCH 06/24] wip inputJSON + cleanup --- src/dapp/libexec/dapp/dapp-verify-contract | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/dapp/libexec/dapp/dapp-verify-contract b/src/dapp/libexec/dapp/dapp-verify-contract index 84773c33f..901642b9e 100755 --- a/src/dapp/libexec/dapp/dapp-verify-contract +++ b/src/dapp/libexec/dapp/dapp-verify-contract @@ -45,6 +45,11 @@ else fi meta=$(jshon <<<"$contract" -e metadata -u) version=$(jshon <<<"$meta" -e compiler -e version -u) +sources=$(jshon <<<"$meta" -e sources) +language=$(jshon <<<"$meta" -e language) +remappings=$(jshon <<<"$meta" -e settings -e remappings) +optimizer=$(jshon <<<"$meta" -e settings -e optimizer) +evmVersion=$(jshon <<<"meta" -e settings -e evmVersion) file=$(jshon <<<"$meta" -e settings -e compilationTarget -k) optimized=$(jshon <<<"$meta" -e settings -e optimizer -e enabled -u) runs=$(jshon <<<"$meta" -e settings -e optimizer -e runs -u) @@ -90,13 +95,24 @@ fi if [[ $1 = "--multiple" ]]; then # Standard Input JSON - inputJSON=$(dapp mk-standard-json) + + inputJSON=$(cat <<-EOF + { + "language": "$language", + "sources": "$sources", + "settings": { + "remappings": "$remappings", + "optimizer": "$optimizer", + "evmVersion": "$evmVersion" + } + } +EOF + ) params=( "module=contract" "action=verifysourcecode" "contractname=$contractName" "contractaddress=$address" "sourcecode=$inputJSON" "codeformat=solidity-standard-json-input" - "optimizationUsed=$optimized" "runs=$runs" "apikey=$ETHERSCAN_API_KEY" ) From 860072bbe4830388953b678d3c96531e7477b731 Mon Sep 17 00:00:00 2001 From: Nazzareno Massari Date: Tue, 20 Apr 2021 18:13:38 +0100 Subject: [PATCH 07/24] refactor to remove duplication --- src/dapp/libexec/dapp/dapp-verify-contract | 50 ++++++++-------------- 1 file changed, 19 insertions(+), 31 deletions(-) diff --git a/src/dapp/libexec/dapp/dapp-verify-contract b/src/dapp/libexec/dapp/dapp-verify-contract index 901642b9e..6e2e93fb8 100755 --- a/src/dapp/libexec/dapp/dapp-verify-contract +++ b/src/dapp/libexec/dapp/dapp-verify-contract @@ -116,25 +116,6 @@ EOF "apikey=$ETHERSCAN_API_KEY" ) - query=$(printf "&%s" "${params[@]}") - - count=0 - while [ $count -lt 5 ]; do - sleep 10 - - response=$(curl -fsS "$ETHERSCAN_API_URL" -d "$query" \ - --data-urlencode "compilerversion=$version" \ - --data-urlencode "constructorArguements=$constructorArguments" -X POST) - # NOTE: the Arguements typo is in etherscan's API - - status=$(jshon <<<"$response" -e status -u) - guid=$(jshon <<<"$response" -e result -u) - message=$(jshon <<<"$response" -e message -u) - count=$((count + 1)) - - [[ $status = 1 ]] && break; - done - else params=( @@ -152,27 +133,34 @@ else . ) - query=$(printf "&%s" "${params[@]}") +fi + +query=$(printf "&%s" "${params[@]}") - count=0 - while [ $count -lt 5 ]; do - sleep 10 +count=0 +while [ $count -lt 5 ]; do + sleep 10 + if [[ $1 = "--multiple" ]]; then + response=$(curl -fsS "$ETHERSCAN_API_URL" -d "$query" \ + --data-urlencode "compilerversion=$version" \ + --data-urlencode "constructorArguements=$constructorArguments" -X POST) + # NOTE: the Arguements typo is in etherscan's API + else response=$(curl -fsS "$ETHERSCAN_API_URL" -d "$query" \ --data-urlencode "compilerversion=$version" \ --data-urlencode "sourceCode@"<(echo "$source") \ --data-urlencode "constructorArguements=$constructorArguments" -X POST) # NOTE: the Arguements typo is in etherscan's API + fi - status=$(jshon <<<"$response" -e status -u) - guid=$(jshon <<<"$response" -e result -u) - message=$(jshon <<<"$response" -e message -u) - count=$((count + 1)) - - [[ $status = 1 ]] && break; - done + status=$(jshon <<<"$response" -e status -u) + guid=$(jshon <<<"$response" -e result -u) + message=$(jshon <<<"$response" -e message -u) + count=$((count + 1)) -fi + [[ $status = 1 ]] && break; +done [[ $status = 0 && $message = "Contract source code already verified" ]] && { echo >&2 "Contract source code already verified." From 5e90f9937b57a6fcc0fafa2e5801405959db9647 Mon Sep 17 00:00:00 2001 From: Nazzareno Massari Date: Tue, 20 Apr 2021 18:33:53 +0100 Subject: [PATCH 08/24] add --multiple flag env variable --- src/dapp/libexec/dapp/dapp-verify-contract | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dapp/libexec/dapp/dapp-verify-contract b/src/dapp/libexec/dapp/dapp-verify-contract index 6e2e93fb8..32a6fbd95 100755 --- a/src/dapp/libexec/dapp/dapp-verify-contract +++ b/src/dapp/libexec/dapp/dapp-verify-contract @@ -92,7 +92,7 @@ else optimized=0 fi -if [[ $1 = "--multiple" ]]; then +if [[ $DAPP_VERIFY_CONTRACT_MULTIPLE == yes ]]; then # Standard Input JSON @@ -141,7 +141,7 @@ count=0 while [ $count -lt 5 ]; do sleep 10 - if [[ $1 = "--multiple" ]]; then + if [[ $DAPP_VERIFY_CONTRACT_MULTIPLE == yes ]]; then response=$(curl -fsS "$ETHERSCAN_API_URL" -d "$query" \ --data-urlencode "compilerversion=$version" \ --data-urlencode "constructorArguements=$constructorArguments" -X POST) From 50f0adf678ee687156e04247587d6ded950422df Mon Sep 17 00:00:00 2001 From: Nazzareno Massari Date: Tue, 20 Apr 2021 18:41:22 +0100 Subject: [PATCH 09/24] add --verify-multiple env variable to dapp --- src/dapp/libexec/dapp/dapp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/dapp/libexec/dapp/dapp b/src/dapp/libexec/dapp/dapp index 243c32ab8..e4182ad1e 100755 --- a/src/dapp/libexec/dapp/dapp +++ b/src/dapp/libexec/dapp/dapp @@ -161,6 +161,7 @@ while [[ $1 ]]; do export HEVM_RPC=yes;; --verify) export DAPP_VERIFY_CONTRACT=yes;; + --verify-multiple) export DAPP_VERIFY_CONTRACT_MULTIPLE=yes;; --async) export DAPP_ASYNC=yes;; From fde5c0733f128e8fe8c6da01a866fcf79942e003 Mon Sep 17 00:00:00 2001 From: Nazzareno Massari Date: Tue, 20 Apr 2021 19:25:26 +0100 Subject: [PATCH 10/24] add verify-multiple to dapp options --- src/dapp/libexec/dapp/dapp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/dapp/libexec/dapp/dapp b/src/dapp/libexec/dapp/dapp index e4182ad1e..4b311d882 100755 --- a/src/dapp/libexec/dapp/dapp +++ b/src/dapp/libexec/dapp/dapp @@ -35,6 +35,7 @@ ### ### Deployment options: ### verify verify contract on etherscan +### verify-multiple multifile verification on etherscan ### ### Contract verifying options: ### async don't wait for confirmation From 609716f40f42492dd4683a0c21e03f9fa8ca318b Mon Sep 17 00:00:00 2001 From: Nazzareno Massari Date: Tue, 20 Apr 2021 19:25:46 +0100 Subject: [PATCH 11/24] cleanup --- src/dapp/libexec/dapp/dapp-verify-contract | 1 - 1 file changed, 1 deletion(-) diff --git a/src/dapp/libexec/dapp/dapp-verify-contract b/src/dapp/libexec/dapp/dapp-verify-contract index 32a6fbd95..00ac6e3e6 100755 --- a/src/dapp/libexec/dapp/dapp-verify-contract +++ b/src/dapp/libexec/dapp/dapp-verify-contract @@ -1,7 +1,6 @@ #!/usr/bin/env bash ### dapp-verify-contract -- verify contract souce on etherscan ### Usage: dapp verify-contract :
[constructorArgs] -### Option: --multiple for standard-json multi-file verification set -e From d24f9b60310fd6e649ec3dfc7a1ea876fca92794 Mon Sep 17 00:00:00 2001 From: Nazzareno Massari Date: Fri, 7 May 2021 23:43:44 +0100 Subject: [PATCH 12/24] add verify multiple to dapp-mk-standard-json --- src/dapp/libexec/dapp/dapp-mk-standard-json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/dapp/libexec/dapp/dapp-mk-standard-json b/src/dapp/libexec/dapp/dapp-mk-standard-json index fc15d5394..afb6f554f 100755 --- a/src/dapp/libexec/dapp/dapp-mk-standard-json +++ b/src/dapp/libexec/dapp/dapp-mk-standard-json @@ -29,7 +29,10 @@ for root, dirnames, filenames in os.walk(src): tmpljson["sources"]={} for f in files: tmpljson["sources"][f]={} - tmpljson["sources"][f]["urls"] = [f] + if os.getenv('DAPP_VERIFY_CONTRACT_MULTIPLE') == "yes": + tmpljson["sources"][f]["content"] = [f.read()] + else + tmpljson["sources"][f]["urls"] = [f] if os.getenv('DAPP_REMAPPINGS') is None or os.getenv('DAPP_REMAPPINGS') == "": tmpljson["settings"].pop("remappings", None) From c61d06e370c6912146fbab50c94f9c73c5fcbc04 Mon Sep 17 00:00:00 2001 From: Nazzareno Massari Date: Fri, 7 May 2021 23:50:00 +0100 Subject: [PATCH 13/24] remove wip inputJSON in favour of mk-standard-json --- src/dapp/libexec/dapp/dapp-verify-contract | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/src/dapp/libexec/dapp/dapp-verify-contract b/src/dapp/libexec/dapp/dapp-verify-contract index 00ac6e3e6..06b068b29 100755 --- a/src/dapp/libexec/dapp/dapp-verify-contract +++ b/src/dapp/libexec/dapp/dapp-verify-contract @@ -44,11 +44,6 @@ else fi meta=$(jshon <<<"$contract" -e metadata -u) version=$(jshon <<<"$meta" -e compiler -e version -u) -sources=$(jshon <<<"$meta" -e sources) -language=$(jshon <<<"$meta" -e language) -remappings=$(jshon <<<"$meta" -e settings -e remappings) -optimizer=$(jshon <<<"$meta" -e settings -e optimizer) -evmVersion=$(jshon <<<"meta" -e settings -e evmVersion) file=$(jshon <<<"$meta" -e settings -e compilationTarget -k) optimized=$(jshon <<<"$meta" -e settings -e optimizer -e enabled -u) runs=$(jshon <<<"$meta" -e settings -e optimizer -e runs -u) @@ -95,18 +90,7 @@ if [[ $DAPP_VERIFY_CONTRACT_MULTIPLE == yes ]]; then # Standard Input JSON - inputJSON=$(cat <<-EOF - { - "language": "$language", - "sources": "$sources", - "settings": { - "remappings": "$remappings", - "optimizer": "$optimizer", - "evmVersion": "$evmVersion" - } - } -EOF - ) + inputJSON=$(dapp mk-standard-json) params=( "module=contract" "action=verifysourcecode" From 15c58d2a2528f2a671f19d18cf3ac9236d613ac9 Mon Sep 17 00:00:00 2001 From: Nazzareno Massari Date: Mon, 10 May 2021 21:08:52 +0100 Subject: [PATCH 14/24] fix else syntax --- src/dapp/libexec/dapp/dapp-mk-standard-json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dapp/libexec/dapp/dapp-mk-standard-json b/src/dapp/libexec/dapp/dapp-mk-standard-json index afb6f554f..c2ac88809 100755 --- a/src/dapp/libexec/dapp/dapp-mk-standard-json +++ b/src/dapp/libexec/dapp/dapp-mk-standard-json @@ -31,7 +31,7 @@ for f in files: tmpljson["sources"][f]={} if os.getenv('DAPP_VERIFY_CONTRACT_MULTIPLE') == "yes": tmpljson["sources"][f]["content"] = [f.read()] - else + else: tmpljson["sources"][f]["urls"] = [f] if os.getenv('DAPP_REMAPPINGS') is None or os.getenv('DAPP_REMAPPINGS') == "": From 7fd80f244e2a7f82b02ba9ef870f2f249ca8956e Mon Sep 17 00:00:00 2001 From: Nazzareno Massari Date: Tue, 11 May 2021 11:29:42 +0100 Subject: [PATCH 15/24] add verify-multiple to dapp OPTS --- src/dapp/libexec/dapp/dapp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/dapp/libexec/dapp/dapp b/src/dapp/libexec/dapp/dapp index 4b311d882..372c72b3e 100755 --- a/src/dapp/libexec/dapp/dapp +++ b/src/dapp/libexec/dapp/dapp @@ -82,6 +82,7 @@ smtdebug print the SMT queries produced by hevm Deployment options: verify verify contract on etherscan +verify-multiple multifile verification on etherscan Contract verifying options: async don't wait for confirmation From 2ece0556cf6c092edc1f3413bca52e6a3a62e291 Mon Sep 17 00:00:00 2001 From: Nazzareno Massari Date: Mon, 17 May 2021 13:41:37 +0100 Subject: [PATCH 16/24] Add --verify-multiple to dapp docs --- src/dapp/README.md | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/src/dapp/README.md b/src/dapp/README.md index fa7ac10cd..f84e3ceb0 100644 --- a/src/dapp/README.md +++ b/src/dapp/README.md @@ -234,30 +234,31 @@ To deploy a contract, you can use `dapp create`: dapp create Dapptutorial [] [] ``` -The `--verify` flag verifies the contract on etherscan (requires `ETHERSCAN_API_KEY`). +The `--verify` and `--verify-multiple` flags verify the contract/s on etherscan (requires `ETHERSCAN_API_KEY`). ## Configuration The commands of `dapp` can be customized with environment variables or flags. These variables can be set at the prompt or in a `.dapprc` file. -| Variable | Default | Synopsis | -|----------------------------|----------------------------|--------------------------------------------------------------------------------------------------------------------------------------------| -| `DAPP_SRC` | `src` | Project Solidity source directory | -| `DAPP_LIB` | `lib` | Directory for installed Dapp packages | -| `DAPP_OUT` | `out` | Directory for compilation artifacts | -| `DAPP_ROOT` | `.` | Root directory of compilation | -| `DAPP_SOLC_VERSION` | n/a | Solidity compiler version to use | -| `DAPP_SOLC` | n/a | solc binary to use | -| `DAPP_VERBOSE` | n/a | Produce more `dapp test` output | -| `DAPP_LIBRARIES` | automatically deployed | Library addresses to link to | -| `DAPP_SKIP_BUILD` | n/a | Avoid compiling this time | -| `DAPP_LINK_TEST_LIBRARIES` | `1` when testing; else `0` | Compile with libraries | -| `DAPP_VERIFY_CONTRACT` | `yes` | Attempt Etherscan verification | -| `DAPP_STANDARD_JSON` | $(dapp mk-standard-json) | [Solidity compilation options](https://docs.soliditylang.org/en/latest/using-the-compiler.html#compiler-input-and-output-json-description) | -| `DAPP_REMAPPINGS` | $(dapp remappings) | [Solidity remappings](https://docs.soliditylang.org/en/latest/using-the-compiler.html#path-remapping) | -| `DAPP_BUILD_OPTIMIZE` | no | Activate Solidity optimizer | -| `DAPP_BUILD_OPTIMIZE_RUNS` | 200 | Set the optimizer runs | +| Variable | Default | Synopsis | +|---------------------------------|----------------------------|---------------------------------------------------------------------------------------------------------------------------------------| +| `DAPP_SRC` | `src` | Project Solidity source directory | +| `DAPP_LIB` | `lib` | Directory for installed Dapp packages | +| `DAPP_OUT` | `out` | Directory for compilation artifacts | +| `DAPP_ROOT` | `.` | Root directory of compilation | +| `DAPP_SOLC_VERSION` | n/a | Solidity compiler version to use | +| `DAPP_SOLC` | n/a | solc binary to use | +| `DAPP_VERBOSE` | n/a | Produce more `dapp test` output | +| `DAPP_LIBRARIES` | automatically deployed | Library addresses to link to | +| `DAPP_SKIP_BUILD` | n/a | Avoid compiling this time | +| `DAPP_LINK_TEST_LIBRARIES` | `1` when testing; else `0` | Compile with libraries | +| `DAPP_VERIFY_CONTRACT` | `yes` | Attempt Etherscan verification | +| `DAPP_VERIFY_CONTRACT_MULTIPLE` | `yes` | Attempt Etherscan multifile verification | +| `DAPP_STANDARD_JSON` | $(dapp mk-standard-json) | [Solidity compilation options](https://docs.soliditylang.org/en/latest/using-the-compiler.html#compiler-input-and-output-json-description) | +| `DAPP_REMAPPINGS` | $(dapp remappings) | [Solidity remappings](https://docs.soliditylang.org/en/latest/using-the-compiler.html#path-remapping) | +| `DAPP_BUILD_OPTIMIZE` | no | Activate Solidity optimizer | +| `DAPP_BUILD_OPTIMIZE_RUNS` | 200 | Set the optimizer runs | A global (always loaded) config file is located in `~/.dapprc`. A local `.dapprc` can also be defined in your project's root, which overrides variables in the global config. @@ -421,7 +422,7 @@ for key bindings for navigation. dapp-create -- deploy a compiled contract (--verify on Etherscan) Usage: dapp create or dapp create : - Add --verify and export your ETHERSCAN_API_KEY to auto-verify on Etherscan + Add --verify or --verify-multiple and export your ETHERSCAN_API_KEY to auto-verify on Etherscan ### `dapp address` @@ -468,7 +469,7 @@ Requires `ETHERSCAN_API_KEY` to be set. `seth chain` will be used to determine on which network the contract is to be verified. -Automatically run when the `--verify` flag is passed to `dapp create`. +Automatically run when the `--verify` or `--verify-multiple` flag is passed to `dapp create`. ### `dapp mk-standard-json` @@ -481,3 +482,4 @@ The following environment variables can be used to override settings: - `DAPP_BUILD_OPTIMIZE` - `DAPP_BUILD_OPTIMIZE_RUNS` - `DAPP_LIBRARIES` +- `DAPP_VERIFY_CONTRACT_MULTIPLE` From 7f9b3874705dc236139a3db3be354249868fa6a0 Mon Sep 17 00:00:00 2001 From: Nazzareno Massari Date: Mon, 17 May 2021 14:18:52 +0100 Subject: [PATCH 17/24] fix dapp-create --- src/dapp/libexec/dapp/dapp-create | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dapp/libexec/dapp/dapp-create b/src/dapp/libexec/dapp/dapp-create index e27fe3672..59ec460a7 100755 --- a/src/dapp/libexec/dapp/dapp-create +++ b/src/dapp/libexec/dapp/dapp-create @@ -41,7 +41,7 @@ bin=$(jq .evm.bytecode.object -r <<< "$contract") type=$(seth --abi-constructor <<< "$abi") address=$(set -x; seth send --create "$bin" "${type/constructor/${1#*:}}" "${@:2}") -[[ $DAPP_VERIFY_CONTRACT ]] && { +[[ $DAPP_VERIFY_CONTRACT || $DAPP_VERIFY_CONTRACT_MULTIPLE ]] && { echo >&2 "Verifying contract at $address" sleep 5 # give etherscan some time to process the block dapp verify-contract "$path":"${1#*:}" "$address" "${@:2}" From 290ce315fdebcfad1329ed0b21a43493d7c031d3 Mon Sep 17 00:00:00 2001 From: Nazzareno Massari Date: Tue, 18 May 2021 17:27:32 +0100 Subject: [PATCH 18/24] fix mk-standard-json content input json --- src/dapp/libexec/dapp/dapp-mk-standard-json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/dapp/libexec/dapp/dapp-mk-standard-json b/src/dapp/libexec/dapp/dapp-mk-standard-json index c2ac88809..3927e38e7 100755 --- a/src/dapp/libexec/dapp/dapp-mk-standard-json +++ b/src/dapp/libexec/dapp/dapp-mk-standard-json @@ -30,7 +30,8 @@ tmpljson["sources"]={} for f in files: tmpljson["sources"][f]={} if os.getenv('DAPP_VERIFY_CONTRACT_MULTIPLE') == "yes": - tmpljson["sources"][f]["content"] = [f.read()] + content = open(f, "r"); + tmpljson["sources"][f]["content"] = [content.read()] else: tmpljson["sources"][f]["urls"] = [f] From 24290a08aa35199454693c46120466522177fd75 Mon Sep 17 00:00:00 2001 From: Nazzareno Massari Date: Wed, 19 May 2021 04:32:35 +0100 Subject: [PATCH 19/24] Fix mk-standard-json by filtering out .t.sol sources --- src/dapp/libexec/dapp/dapp-mk-standard-json | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/dapp/libexec/dapp/dapp-mk-standard-json b/src/dapp/libexec/dapp/dapp-mk-standard-json index 3927e38e7..0c89fa861 100755 --- a/src/dapp/libexec/dapp/dapp-mk-standard-json +++ b/src/dapp/libexec/dapp/dapp-mk-standard-json @@ -27,12 +27,17 @@ for root, dirnames, filenames in os.walk(src): files.append(os.path.join(root, filename)) tmpljson["sources"]={} -for f in files: - tmpljson["sources"][f]={} - if os.getenv('DAPP_VERIFY_CONTRACT_MULTIPLE') == "yes": - content = open(f, "r"); - tmpljson["sources"][f]["content"] = [content.read()] - else: + +if os.getenv('DAPP_VERIFY_CONTRACT_MULTIPLE') == "yes": + for f in files: + if f.endswith(".t.sol"): + continue + else: + tmpljson["sources"][f]={} + content = open(f, "r"); + tmpljson["sources"][f]["content"] = [content.read()] +else: + for f in files: tmpljson["sources"][f]["urls"] = [f] if os.getenv('DAPP_REMAPPINGS') is None or os.getenv('DAPP_REMAPPINGS') == "": From 3e352d5dccacd0a1e0ed60ecc8b013edd68c7baa Mon Sep 17 00:00:00 2001 From: Nazzareno Massari Date: Wed, 19 May 2021 17:41:33 +0100 Subject: [PATCH 20/24] Fix dapp-mk-standard-json, failing ci --- src/dapp/libexec/dapp/dapp-mk-standard-json | 1 + 1 file changed, 1 insertion(+) diff --git a/src/dapp/libexec/dapp/dapp-mk-standard-json b/src/dapp/libexec/dapp/dapp-mk-standard-json index 0c89fa861..953c2d0df 100755 --- a/src/dapp/libexec/dapp/dapp-mk-standard-json +++ b/src/dapp/libexec/dapp/dapp-mk-standard-json @@ -38,6 +38,7 @@ if os.getenv('DAPP_VERIFY_CONTRACT_MULTIPLE') == "yes": tmpljson["sources"][f]["content"] = [content.read()] else: for f in files: + tmpljson["sources"][f]={} tmpljson["sources"][f]["urls"] = [f] if os.getenv('DAPP_REMAPPINGS') is None or os.getenv('DAPP_REMAPPINGS') == "": From af32e3fb8f172c5c00143a52f88423f8e9eae437 Mon Sep 17 00:00:00 2001 From: Nazzareno Massari Date: Tue, 1 Jun 2021 12:49:44 +0100 Subject: [PATCH 21/24] Fix sourceCode camel case --- src/dapp/libexec/dapp/dapp-verify-contract | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dapp/libexec/dapp/dapp-verify-contract b/src/dapp/libexec/dapp/dapp-verify-contract index 06b068b29..796d602d3 100755 --- a/src/dapp/libexec/dapp/dapp-verify-contract +++ b/src/dapp/libexec/dapp/dapp-verify-contract @@ -95,7 +95,7 @@ if [[ $DAPP_VERIFY_CONTRACT_MULTIPLE == yes ]]; then params=( "module=contract" "action=verifysourcecode" "contractname=$contractName" "contractaddress=$address" - "sourcecode=$inputJSON" "codeformat=solidity-standard-json-input" + "sourceCode=$inputJSON" "codeformat=solidity-standard-json-input" "apikey=$ETHERSCAN_API_KEY" ) From efff9439fa79fb161cc76e3c1a04ae6faecf0837 Mon Sep 17 00:00:00 2001 From: Nazzareno Massari Date: Mon, 7 Jun 2021 20:51:50 +0100 Subject: [PATCH 22/24] Fix content read in dapp-mk-standard-json --- src/dapp/libexec/dapp/dapp-mk-standard-json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dapp/libexec/dapp/dapp-mk-standard-json b/src/dapp/libexec/dapp/dapp-mk-standard-json index 953c2d0df..3dfc27211 100755 --- a/src/dapp/libexec/dapp/dapp-mk-standard-json +++ b/src/dapp/libexec/dapp/dapp-mk-standard-json @@ -35,7 +35,7 @@ if os.getenv('DAPP_VERIFY_CONTRACT_MULTIPLE') == "yes": else: tmpljson["sources"][f]={} content = open(f, "r"); - tmpljson["sources"][f]["content"] = [content.read()] + tmpljson["sources"][f]["content"] = content.read() else: for f in files: tmpljson["sources"][f]={} From c227e2a64a0492fe8a3fc801238f20715f09b4ba Mon Sep 17 00:00:00 2001 From: Nazzareno Massari Date: Wed, 9 Jun 2021 15:03:42 +0100 Subject: [PATCH 23/24] Split --verify-multiple in dapp-verify-contracts + fix typo in dapp-verify-contract --- src/dapp/libexec/dapp/dapp-create | 8 +- src/dapp/libexec/dapp/dapp-verify-contract | 55 ++------ src/dapp/libexec/dapp/dapp-verify-contracts | 147 ++++++++++++++++++++ 3 files changed, 169 insertions(+), 41 deletions(-) create mode 100755 src/dapp/libexec/dapp/dapp-verify-contracts diff --git a/src/dapp/libexec/dapp/dapp-create b/src/dapp/libexec/dapp/dapp-create index 59ec460a7..644562ce7 100755 --- a/src/dapp/libexec/dapp/dapp-create +++ b/src/dapp/libexec/dapp/dapp-create @@ -41,10 +41,16 @@ bin=$(jq .evm.bytecode.object -r <<< "$contract") type=$(seth --abi-constructor <<< "$abi") address=$(set -x; seth send --create "$bin" "${type/constructor/${1#*:}}" "${@:2}") -[[ $DAPP_VERIFY_CONTRACT || $DAPP_VERIFY_CONTRACT_MULTIPLE ]] && { +[[ $DAPP_VERIFY_CONTRACT ]] && { echo >&2 "Verifying contract at $address" sleep 5 # give etherscan some time to process the block dapp verify-contract "$path":"${1#*:}" "$address" "${@:2}" } +[[ $DAPP_VERIFY_CONTRACT_MULTIPLE ]] && { + echo >&2 "Verifying contracts at $address" + sleep 5 # give etherscan some time to process the block + dapp verify-contracts "$path":"${1#*:}" "$address" "${@:2}" +} + seth --to-checksum-address "$address" diff --git a/src/dapp/libexec/dapp/dapp-verify-contract b/src/dapp/libexec/dapp/dapp-verify-contract index 796d602d3..25fe838ca 100755 --- a/src/dapp/libexec/dapp/dapp-verify-contract +++ b/src/dapp/libexec/dapp/dapp-verify-contract @@ -1,5 +1,5 @@ #!/usr/bin/env bash -### dapp-verify-contract -- verify contract souce on etherscan +### dapp-verify-contract -- verify contract source on etherscan ### Usage: dapp verify-contract :
[constructorArgs] set -e @@ -33,7 +33,6 @@ esac path=${1?contractname} name=${path#*:} -contractName=$(basename "$path") address=${2?contractaddress} # combined-json has a sourceList field @@ -86,37 +85,20 @@ else optimized=0 fi -if [[ $DAPP_VERIFY_CONTRACT_MULTIPLE == yes ]]; then - - # Standard Input JSON - - inputJSON=$(dapp mk-standard-json) - - params=( +params=( "module=contract" "action=verifysourcecode" - "contractname=$contractName" "contractaddress=$address" - "sourceCode=$inputJSON" "codeformat=solidity-standard-json-input" + "contractname=$name" "contractaddress=$address" + "optimizationUsed=$optimized" "runs=$runs" "apikey=$ETHERSCAN_API_KEY" - ) - -else +) - params=( - "module=contract" "action=verifysourcecode" - "contractname=$name" "contractaddress=$address" - "optimizationUsed=$optimized" "runs=$runs" - "apikey=$ETHERSCAN_API_KEY" - ) +source=$(hevm flatten --source-file "$file" --json-file "$DAPP_JSON" --dapp-root "$DAPP_ROOT") - source=$(hevm flatten --source-file "$file" --json-file "$DAPP_JSON" --dapp-root "$DAPP_ROOT") - - source=$(cat <<. - //Verified using https://dapp.tools - "$source" +source=$(cat <<. +// Verified using https://dapp.tools +$source . - ) - -fi +) query=$(printf "&%s" "${params[@]}") @@ -124,18 +106,11 @@ count=0 while [ $count -lt 5 ]; do sleep 10 - if [[ $DAPP_VERIFY_CONTRACT_MULTIPLE == yes ]]; then - response=$(curl -fsS "$ETHERSCAN_API_URL" -d "$query" \ - --data-urlencode "compilerversion=$version" \ - --data-urlencode "constructorArguements=$constructorArguments" -X POST) - # NOTE: the Arguements typo is in etherscan's API - else - response=$(curl -fsS "$ETHERSCAN_API_URL" -d "$query" \ - --data-urlencode "compilerversion=$version" \ - --data-urlencode "sourceCode@"<(echo "$source") \ - --data-urlencode "constructorArguements=$constructorArguments" -X POST) - # NOTE: the Arguements typo is in etherscan's API - fi + response=$(curl -fsS "$ETHERSCAN_API_URL" -d "$query" \ + --data-urlencode "compilerversion=$version" \ + --data-urlencode "sourceCode@"<(echo "$source") \ + --data-urlencode "constructorArguements=$constructorArguments" -X POST) + # NOTE: the Arguements typo is in etherscan's API status=$(jshon <<<"$response" -e status -u) guid=$(jshon <<<"$response" -e result -u) diff --git a/src/dapp/libexec/dapp/dapp-verify-contracts b/src/dapp/libexec/dapp/dapp-verify-contracts new file mode 100755 index 000000000..ea0476f1f --- /dev/null +++ b/src/dapp/libexec/dapp/dapp-verify-contracts @@ -0,0 +1,147 @@ +#!/usr/bin/env bash +### dapp-verify-contracts -- verify contracts source on etherscan +### Usage: dapp verify-contracts :
[constructorArgs] + +set -e + +[[ $ETHERSCAN_API_KEY ]] || { + cat >&2 <<. + You need an Etherscan Api Key to verify contracts. + Create one at https://etherscan.io/myapikey + Then export it with \`export ETHERSCAN_API_KEY=xxxxxxxx' +. + exit 1 +} + +[[ $1 ]] || (dapp verify-contracts --help >&2 && exit 1) +[[ $2 ]] || (dapp verify-contracts --help >&2 && exit 1) + +chain=$(seth chain) +case "$chain" in + ethlive|mainnet) + export ETHERSCAN_API_URL=https://api.etherscan.io/api + export ETHERSCAN_URL=https://etherscan.io/address + ;; + ropsten|kovan|rinkeby|goerli) + export ETHERSCAN_API_URL=https://api-$chain.etherscan.io/api + export ETHERSCAN_URL=https://$chain.etherscan.io/address + ;; + *) + echo >&2 "Verification only works on mainnet, ropsten, kovan, rinkeby, and goerli." + exit 1 +esac + +path=${1?contractname} +name=${path#*:} +contractName=$(basename "$path") +address=${2?contractaddress} + +# combined-json has a sourceList field +if [[ $(jq .sourceList "$DAPP_JSON") == null ]]; then + contract=$(<"$DAPP_JSON" jq -r ".contracts[\"${path/:*/}\"][\"$name\"]") +else + contract=$(<"$DAPP_JSON" jq -r ".contracts[\"$path\"]") +fi +meta=$(jshon <<<"$contract" -e metadata -u) +version=$(jshon <<<"$meta" -e compiler -e version -u) + +abi=$(jq '.["abi"]' -r <<< "$contract") +type=$(seth --abi-constructor <<< "$abi") +constructor=${type/constructor/${1#*:}} + +if [[ $3 ]]; then + constructorArguments=$(seth calldata "$constructor" "${@:3}") + constructorArguments=${constructorArguments#0x} + constructorArguments=${constructorArguments:8} +fi + + +# Etherscan requires leading 'v' which isn't in the artifacts +version="v${version}" + +# Get the list of supported solc versions and compare +# Etherscan uses the js solc, which is not guaranteed to match the C distribution signature + +version_list=$(curl -fsS "https://raw.githubusercontent.com/ethereum/solc-bin/gh-pages/bin/list.txt") +# There have been a couple of instances where the solc js release used by +# Etherscan does not match the tag of the C distributions. +if [[ $version_list != *"$version"* ]]; then + regex="(.+commit+.)" + # Version incompatible with js release + echo "Compiler version $version is not compatible with etherscan" + if [[ $version =~ $regex ]]; then + version_proto=${BASH_REMATCH[1]} + version=$(echo "$version_list" | grep -o "${version_proto}\{8\}") + echo "Attempting ${version}" + fi +fi + +# Standard Input JSON + +inputJSON=$(dapp mk-standard-json) + +params=( +"module=contract" "action=verifysourcecode" +"contractname=$contractName" "contractaddress=$address" +"codeformat=solidity-standard-json-input" +"apikey=$ETHERSCAN_API_KEY" +) + +query=$(printf "&%s" "${params[@]}") + +count=0 +while [ $count -lt 5 ]; do + sleep 10 + + response=$(curl --location --request POST "$ETHERSCAN_API_URL" \ + --header 'Content-Type: application/x-www-form-urlencoded' \ + -d "$query" \ + --data-urlencode "compilerversion=$version" \ + --data-urlencode "sourceCode=$inputJSON" \ + --data-urlencode "constructorArguements=$constructorArguments") + # NOTE: the Arguements typo is in etherscan's API + + status=$(jshon <<<"$response" -e status -u) + guid=$(jshon <<<"$response" -e result -u) + message=$(jshon <<<"$response" -e message -u) + count=$((count + 1)) + + [[ $status = 1 ]] && break; +done + +[[ $status = 0 && $message = "Contract source code already verified" ]] && { + echo >&2 "Contract source code already verified." + echo >&2 "Go to $ETHERSCAN_URL/$2#code" + exit 0 +} + +[[ $status = 0 ]] && { + echo >&2 "There was an error verifying this contract." + echo >&2 "Response: $message" + echo >&2 "Details: $guid" + exit 1 +} + + + + +[[ $DAPP_ASYNC == yes ]] && exit + +sleep 20 +response=$(curl -fsS "$ETHERSCAN_API_URL" \ +-d "module=contract&action=checkverifystatus&guid=$guid&apikey=$ETHERSCAN_API_KEY") + +status=$(jshon <<<"$response" -e status -u) +result=$(jshon <<<"$response" -e result -u) + +[[ $status = 1 ]] && { + echo >&2 "$result" + echo >&2 "Go to $ETHERSCAN_URL/$2#code" + exit 0 +} + +[[ $status = 0 ]] && { + echo >&2 "Failure" + echo >&2 "$result" + exit 1 +} From 9868d395de4833cd932d7cabe0afd0313a611893 Mon Sep 17 00:00:00 2001 From: Nazzareno Massari Date: Wed, 9 Jun 2021 15:14:48 +0100 Subject: [PATCH 24/24] Cleanup --- src/dapp/libexec/dapp/dapp-verify-contract | 4 ++++ src/dapp/libexec/dapp/dapp-verify-contracts | 3 +++ 2 files changed, 7 insertions(+) diff --git a/src/dapp/libexec/dapp/dapp-verify-contract b/src/dapp/libexec/dapp/dapp-verify-contract index 25fe838ca..ad2013849 100755 --- a/src/dapp/libexec/dapp/dapp-verify-contract +++ b/src/dapp/libexec/dapp/dapp-verify-contract @@ -6,9 +6,12 @@ set -e [[ $ETHERSCAN_API_KEY ]] || { cat >&2 <<. + You need an Etherscan Api Key to verify contracts. Create one at https://etherscan.io/myapikey + Then export it with \`export ETHERSCAN_API_KEY=xxxxxxxx' + . exit 1 } @@ -96,6 +99,7 @@ source=$(hevm flatten --source-file "$file" --json-file "$DAPP_JSON" --dapp-root source=$(cat <<. // Verified using https://dapp.tools + $source . ) diff --git a/src/dapp/libexec/dapp/dapp-verify-contracts b/src/dapp/libexec/dapp/dapp-verify-contracts index ea0476f1f..fb38c4592 100755 --- a/src/dapp/libexec/dapp/dapp-verify-contracts +++ b/src/dapp/libexec/dapp/dapp-verify-contracts @@ -6,9 +6,12 @@ set -e [[ $ETHERSCAN_API_KEY ]] || { cat >&2 <<. + You need an Etherscan Api Key to verify contracts. Create one at https://etherscan.io/myapikey + Then export it with \`export ETHERSCAN_API_KEY=xxxxxxxx' + . exit 1 }