| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- #!/bin/bash
- set -euo pipefail
- function usage() {
- cat<<-EOF >&2
- Usage:
- $(basename "$0") [-h] [-n network] [-s svm] <.so file> <account address> -- Verify that the deployed on-chain bytecode matches the local object file
- where:
- -h show this help text
- -n set the network (mainnet, testnet, devnet. defaults to \$NETWORK if set)
- -s set the svm (solana, fogo. defaults to \$SVM if set)
- EOF
- exit 1
- }
- network=""
- if [[ -n "${NETWORK:-}" ]]; then
- network="$NETWORK"
- fi
- svm=""
- if [[ -n "${SVM:-}" ]]; then
- svm="$SVM"
- fi
- while getopts ':n:s:h' option; do
- case "$option" in
- h) usage
- ;;
- n) network=$OPTARG
- ;;
- s) svm=$OPTARG
- ;;
- :) printf "missing argument for -%s\n" "$OPTARG" >&2
- usage
- ;;
- \?) printf "illegal option: -%s\n" "$OPTARG" >&2
- usage
- ;;
- esac
- done
- shift $((OPTIND - 1))
- # Set moniker based on SVM and network
- case "$svm" in
- solana)
- case "$network" in
- mainnet) moniker="m";;
- testnet) moniker="d";;
- devnet) moniker="l";;
- *) printf "Network not set. Specify with -n\n" >&2
- usage
- ;;
- esac
- ;;
- fogo)
- case "$network" in
- mainnet) moniker="https://mainnet.fogo.io";;
- testnet) moniker="https://testnet-alt.fogo.io";;
- *) printf "Fogo only supports mainnet and testnet. Specify with -n\n" >&2
- usage
- ;;
- esac
- ;;
- *) printf "SVM not set. Specify with -s\n" >&2
- usage
- ;;
- esac
- [ $# -ne 2 ] && usage
- obj_file=$1
- sol_addr=$2
- account_json=$(mktemp)
- account_dump=$(mktemp)
- # Grab account content as JSON
- solana account "$sol_addr" -u $moniker --output-file "$account_json" --output json-compact >/dev/null
- # decode the base64 account data to binary
- jq '.account.data[0]' "$account_json" | sed s/\"//g | base64 -d > "$account_dump"
- # The first 37 bytes are irrelevant, the actual ELF object code starts after,
- # so we drop these bytes. Presumably those bytes correspond to an encoded rust
- # enum constructor?
- # Set the block size to 37 bytes and skip the first block.
- dd bs=37 skip=1 if="$account_dump" of=/tmp/bytecode.dump 2>/dev/null
- hash1=$(sha256sum /tmp/bytecode.dump | cut -f1 -d' ')
- hash2=$(sha256sum "$obj_file" | cut -f1 -d' ')
- echo "Deployed bytecode hash (on $network):"
- echo "$hash1"
- echo "$obj_file hash:"
- echo "$hash2"
- if [ "$hash1" == "$hash2" ]; then
- printf "\033[0;32mSuccessfully verified\033[0m\n";
- exit 0;
- else
- printf "\033[0;31mFailed to verify\033[0m\n" >&2;
- echo "JSON: $account_json" >&2;
- echo "Dump: $account_dump" >&2;
- exit 1;
- fi
|