-
Notifications
You must be signed in to change notification settings - Fork 322
seth: add function selector and calldata encoding/decoding helpers #757
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
4bc8f4d
8dbc0c3
7580325
f23a1fc
3cd32f9
1d517e0
2b400a4
d523c2e
f058816
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
#!/usr/bin/env bash | ||
### seth-4byte -- prints the response from querying 4byte.directory for a given function signature | ||
### Usage: seth 4byte <calldata> [<options>] | ||
### | ||
### Takes a 4 byte function signature and prints matching functions from 4byte.directory. This will also strip | ||
### any appended calldata after the first four bytes | ||
### | ||
### When the --verbose option is used, the full JSON response is printed, otherwise just text signatures are printed | ||
|
||
set -e | ||
[[ $# -eq 1 ]] || seth --fail-usage "$0" | ||
|
||
if [[ $SETH_VERBOSE ]]; then | ||
curl -s "https://www.4byte.directory/api/v1/signatures/?hex_signature=${1:0:10}" | jq . | ||
else | ||
curl -s "https://www.4byte.directory/api/v1/signatures/?hex_signature=${1:0:10}" | jq '.results[] | .text_signature' | ||
fi |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
#!/usr/bin/env bash | ||
### seth-4byte-decode -- querys 4byte.directory to find a matching signature, then decodes the calldata with it | ||
### Usage: seth 4byte-decode <calldata> [<options>] | ||
### | ||
### Querys 4byte.directory to find matching signatures and prompts the user to to select one. The selected | ||
### signature will be used to decode the calldata. | ||
|
||
set -e | ||
[[ $# -eq 1 ]] || seth --fail-usage "$0" | ||
|
||
if [[ -z $SETH_4BYTE_ID ]]; then | ||
# Function signature ID not specified, prompt user to choose a signature | ||
sigs=$(curl -s "https://www.4byte.directory/api/v1/signatures/?hex_signature=${1:0:10}" | jq '.results[] | .text_signature' ) | ||
PS3="Select a function signature by number: " | ||
select sig in $sigs; do | ||
break | ||
done | ||
echo "" # add a line break for easier reading | ||
else | ||
# Function signature ID was specified, so parse results without user input | ||
results=$(curl -s "https://www.4byte.directory/api/v1/signatures/?hex_signature=${1:0:10}" | jq .results[] ) | ||
sigs=$(echo $results | jq '.text_signature') | ||
|
||
# sigs is a string so split it into an array | ||
sigarray=() | ||
for sig in $sigs; do sigarray+=($sig); done | ||
length=${#sigarray[@]} | ||
|
||
# parse the provided ID | ||
if [[ $SETH_4BYTE_ID = earliest ]]; then | ||
# first one added to 4byte is the last in the array | ||
sig=${sigarray[$length-1]} | ||
elif [[ $SETH_4BYTE_ID = latest ]]; then | ||
# last one added to 4byte is the first in the array | ||
sig=${sigarray[0]} | ||
else | ||
# specific ID number provided (if using this option, you may be better off with `seth --calldata-decode`) | ||
query=". | select(.id==$SETH_4BYTE_ID) | .text_signature" | ||
sig=$(echo $results | jq "$query") | ||
fi | ||
fi | ||
|
||
# Exit if no sig found | ||
if [[ -z $sig ]]; then | ||
echo >&2 "seth 4byte-decode: no signature found" | ||
exit 1 | ||
elif [[ $SETH_VERBOSE ]]; then | ||
echo "signature: $sig" | ||
fi | ||
|
||
# Remove leading and trailing quotes from JSON, then decode | ||
sig="${sig//\"}" | ||
seth --calldata-decode $sig $1 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
#!/usr/bin/env bash | ||
### seth-4byte-event -- prints the response from querying 4byte.directory for a given function topic | ||
### Usage: seth 4byte-event <topic> [<options>] | ||
### | ||
### Takes a 32 byte topic and prints the response from querying 4byte.directory for that topic | ||
|
||
set -e | ||
[[ $# -eq 1 ]] || seth --fail-usage "$0" | ||
|
||
if [[ $SETH_VERBOSE ]]; then | ||
curl -s "https://www.4byte.directory/api/v1/event-signatures/?hex_signature=$1" | jq . | ||
else | ||
curl -s "https://www.4byte.directory/api/v1/event-signatures/?hex_signature=$1" | jq '.results[] | .text_signature' | ||
fi |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
#!/usr/bin/env bash | ||
### seth-abi-encode -- ABI encode values, and prints the encoded values without the function signature | ||
### Usage: seth abi-encode <sig> [<args>] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does it make sense to accept a tuple of types and then automatically add some dummy function signature just as an internal implementation detail? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You could, but IMO we should keep the current Also noticed a docs issue with this command, so fixed in d523c2e |
||
### | ||
### ABI encode values based on a provided function signature, slice off the leading the function signature, | ||
### and print the result. It does not matter what the name of the function is, as only the types and values | ||
### affect the output. | ||
|
||
set -e | ||
|
||
x=$(seth calldata $@); # generate full calldata based on function signature | ||
echo "0x${x:10}" # slice off the function signature and only keep the encoded values |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
#!/usr/bin/env bash | ||
### seth-index -- Prints the slot number for the specified mapping type and input data | ||
### Usage: seth index <fromtype> <totype> <fromvalue> <slot> [<lang>] | ||
### | ||
### Prints the slot number for the specified mapping type and input data. For example, | ||
### the balances mapping in DAI is slot 2, so to find the slot where the balance | ||
### is stored for <account>, use | ||
### seth-index address uint256 <account> 2 | ||
Comment on lines
+2
to
+8
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we document the allowed values for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done in d523c2e |
||
### | ||
### `lang` will default to Solidity when not specified. To use Vyper, enter `v`, `vy`, | ||
### or `vyper`. The above example cna be repeated for a Vyper token with | ||
### seth-index address uint256 <account> 2 vyper | ||
|
||
set -e | ||
[[ $# -eq 4 ]] || [[ $# -eq 5 ]] || seth --fail-usage "$0" | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we print usage info we don't have the expected number of params, right now if I run
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done in d523c2e |
||
if [[ $5 = 'vyper' || $5 = 'vy' || $5 = 'v' ]]; then | ||
# note: not guaranteed to be accurate for all Vyper versions since storage layout is not yet stable | ||
# more info: https://twitter.com/big_tech_sux/status/1420159854170152963 | ||
echo >&2 "${0##*/}: warning: not guaranteed to be accurate for all Vyper versions since storage layout is not yet stable" | ||
echo $(seth keccak $(seth abi-encode "x($2,$1)" $4 $3)); | ||
else | ||
echo $(seth keccak $(seth abi-encode "x($1,$2)" $3 $4)); | ||
fi |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could be nice to have an
--optimistic
(I feel lucky) flag to this if we wanna build some larger pipeline where we can't be interactiveThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking that too, just wasn't sure of how we'd want to do it. You can sometimes deduce which sig is the correct one from the calldata, but that can get hairy for complex sigs, and you can't always deduce it
For now I learn towards a simpler approach of having
--optimistic
use the oldest sig 4byte.directory has. Anecdotally this seems to often be the desired one (or at least it was the for the ERC20 methods I used for testing)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wdyt about a
--id
flag that accepts either an id number orearliest
/latest
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, what would be the use case for specifying an ID? If you know the ID then presumably you also know the function signature, meaning you could use
seth --calldata-decode
instead ofseth 4byte-decode
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
meh mainly for the ability to specify
earliest
/latest
and id is shorter than using the full sig 🤷
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That seems reasonable enough to me, being able to toggle earliest/latest is nice
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would love some help with my
--id
flag here. In f45ee07 I pushed an attempt that works if I set the env var manually but not with the--id
flag