verify 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. #!/bin/bash
  2. function usage() {
  3. cat <<EOF >&2
  4. Usage:
  5. $(basename "$0") [-h] [-n network] [-r rpc] [-c chain] <.json file> <contract address> -- Verify that the deployed on-chain bytecode matches the local build artifact
  6. where:
  7. -h show this help text
  8. -n set the network (mainnet, testnet, devnet)
  9. -r rpc url
  10. -c set the chain name (required)"
  11. The -n and -r flags are mutually exclusive.
  12. EOF
  13. exit 1
  14. }
  15. chain=""
  16. network=""
  17. rpc=""
  18. while getopts ':hn:r:c:' option; do
  19. case "$option" in
  20. h) usage
  21. ;;
  22. c) chain=$OPTARG
  23. ;;
  24. n) network=$OPTARG
  25. ;;
  26. r) rpc=$OPTARG
  27. ;;
  28. :) printf "missing argument for -%s\n" "$OPTARG" >&2
  29. usage
  30. ;;
  31. \?) printf "illegal option: -%s\n" "$OPTARG" >&2
  32. usage
  33. ;;
  34. esac
  35. done
  36. shift $((OPTIND - 1))
  37. [ $# -ne 2 ] && usage
  38. [[ -z $chain ]] && { echo "Missing chain flag (-c)"; usage; }
  39. json_file=$1
  40. contract_addr=$2
  41. # See if they specified the forge output. Do this before we set the error handling flags because
  42. # this pipeline will intentionally fail if they are using the truffle build output.
  43. use_forge=""
  44. echo "$json_file" | grep "build-forge" > /dev/null
  45. if [[ $? -eq 0 ]]; then
  46. use_forge="true"
  47. fi
  48. set -euo pipefail
  49. # network and rpc flags are mutually exlusive
  50. [[ -n $network && -n $rpc ]] && usage
  51. # if network flag is set, we query the rpc from the cli tool.
  52. if [[ -n $network ]]; then
  53. if ! command -v worm &> /dev/null
  54. then
  55. echo "worm binary could not be found. See installation instructions in clients/js/README.md"
  56. exit 1
  57. fi
  58. rpc=$(worm info rpc "$network" "$chain")
  59. fi
  60. if [[ -z $rpc ]]; then
  61. echo "rpc endpoint or network name required."
  62. usage
  63. fi
  64. # We'll write the bytecodes to temporary files
  65. deployed=$(mktemp)
  66. local=$(mktemp)
  67. if [[ -z $use_forge ]]; then
  68. cat "$json_file" | jq -r .deployedBytecode > "$local"
  69. else
  70. cat "$json_file" | jq -r .deployedBytecode | jq -r .object > "$local"
  71. fi
  72. ret=0
  73. # Grab bytecode from the JSON RPC using the eth_getCode method.
  74. curl "$rpc" \
  75. -X POST \
  76. -H "Content-Type: application/json" \
  77. --data "{\"method\":\"eth_getCode\",\"params\":[\"$contract_addr\",\"latest\"],\"id\":1,\"jsonrpc\":\"2.0\"}" --silent | jq -r .result > "$deployed" || ret=$?
  78. if [ $ret -gt 0 ]; then
  79. printf "\033[0;31mFailed to query eth RPC '%s' while verifying %s on %s\033[0m\n" "$rpc" "$contract_addr" "$chain"
  80. exit 1
  81. fi
  82. # hash, then see if they match up
  83. hash1=$(sha256sum "$deployed" | cut -f1 -d' ')
  84. hash2=$(sha256sum "$local" | cut -f1 -d' ')
  85. if [ "$hash1" == "$hash2" ]; then
  86. printf "\033[0;32mDeployed bytecode of %s on %s matches %s\033[0m\n" "$contract_addr" "$chain" "$json_file";
  87. exit 0;
  88. else
  89. printf "\033[0;31mDeployed bytecode of %s on %s doesn't match %s\033[0m\n" "$contract_addr" "$chain" "$json_file";
  90. echo "deployed hash:"
  91. echo "$hash1"
  92. echo "$json_file hash:"
  93. echo "$hash2"
  94. exit 1;
  95. fi