Skip to content
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

seth events - command errors + proposed improvements #902

Open
ciaranmcveigh-0xa opened this issue Jan 9, 2022 · 0 comments
Open

seth events - command errors + proposed improvements #902

ciaranmcveigh-0xa opened this issue Jan 9, 2022 · 0 comments

Comments

@ciaranmcveigh-0xa
Copy link

ciaranmcveigh-0xa commented Jan 9, 2022

Experiencing a number of errors when trying to execute the "seth events" command

seth --version 0.12.0 running on a mac intel

trying to get the events for a Convex contract https://etherscan.io/address/0x3fe65692bfcd0e6cf84cb1e7d24108e434a7587e#events

seth events -B $(seth --to-hex 13966206) 0x3Fe65692bfCD0e6CF84cB1E7d24108E434A7587e

SETH_ABI =

[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"}],"name":"RewardAdded","type":"event","topic":"0xde88a922e0d3b88b24e9623efeb464919c6bf9f66857a65e2bfcf2ce87a9433d"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"}],"name":"RewardPaid","type":"event","topic":"0xe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e0486"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Staked","type":"event","topic":"0x9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdrawn","type":"event","topic":"0x7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d5"}]

The first issue is in the README https://github.com/dapphub/dapptools/blob/master/src/seth/README.md#seth-events

for

export SETH_ABI=$(seth abi "event Foo(uint bar);")

i get "unknown modifier: ;" after removing the ; it return the json however it still does not have the decorated topics there it need to be run through seth --decorate-abi

i propose changing that section of the README to

export SETH_ABI=$(seth --decorate-abi $(seth abi "event Foo(uint bar)"))

This will yield the correct value for SETH_ABI give the user only inputs the event signature

with that value set when i executed seth events i got back

"Usage: seth --decode-event <abi-json> <event-name> <hexdata>"

the seth events command flow is

seth events -> seth logs -> seth --decode-events -> seth --decode-event

the initial issue is that the --decode-events script is passing in 1 variable to a script that expects 3 https://github.com/dapphub/dapptools/blob/master/src/seth/libexec/seth/seth---decode-events

That 1 variable is one entry from the seth logs command here is an example

{"address":"0x3fe65692bfcd0e6cf84cb1e7d24108e434a7587e","blockHash":"0x86c6652a5a70a494b8ffa2c31f74d77e2d3f1ec5c83865cc6ec9f24c31e756ec","blockNumber":"0xd51933","data":"0x00000000000000000000000000000000000000000000003197662e19ad43bb6f","logIndex":"0x103","removed":false,"topics":["0x7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d5","0x000000000000000000000000275445e66b7cd2e7d20937ba3821e8d20b7224f7"],"transactionHash":"0xf294b477cd3418c75ceb23022c8be729b018f06bc6da97f763a08dda08c12984","transactionIndex":"0xba"}

it appears to me that the --decode-events script should look something like

seth --decode-event $SETH_ABI $event_name "$event"

rather than its current

seth --decode-event "$event"

in terms of getting the event name a simple match on the topic of the log event to the ABI will yield this ie

event_topic = echo $event | jq .topics[0]
event_name = echo $SETH_ABI | jq --argjson v "$event_topic" '.[] | select(.topic==$v)' | jq -r .name

once we have done that we get into the execution of seth --decode-event https://github.com/dapphub/dapptools/blob/master/src/seth/libexec/seth/seth---decode-event

I think there may be a few issues here also

the first comes from these 2 lines

const events = new ethers.utils.Interface(process.argv[2]).events;
console.log(events[process.argv[3]].decode(process.argv[4]).join('\n'))

const events is an json object where the keys are the event signatures and they map to ethers.js type EventFragment ie

{
  'RewardAdded(uint256)': EventFragment {
    name: 'RewardAdded',
    anonymous: false,
    inputs: [ [ParamType] ],
    type: 'event',
    _isFragment: true
  },
  'RewardPaid(address,uint256)': EventFragment {
    name: 'RewardPaid',
    anonymous: false,
    inputs: [ [ParamType], [ParamType] ],
    type: 'event',
    _isFragment: true
  },
  'Staked(address,uint256)': EventFragment {
    name: 'Staked',
    anonymous: false,
    inputs: [ [ParamType], [ParamType] ],
    type: 'event',
    _isFragment: true
  },
  'Withdrawn(address,uint256)': EventFragment {
    name: 'Withdrawn',
    anonymous: false,
    inputs: [ [ParamType], [ParamType] ],
    type: 'event',
    _isFragment: true
  }
}

The first issue is that we're trying to use process.argv[3] which is the event name as the key when in actual fact we need the event signature to match on the json key for now i used some simple regex to get round this however the signature could be constructed from the ABI

// keys in events are event signatures ie Withdrawn(address,uint256)
    regex = "^" + process.argv[3] +"\\("
// From the events list get the mathcing event signature for the given <event-name>
   eventSignature = Object.keys(events).filter((event) => event.match(regex))[0]

back to the actual --decode-event script
this means events[process.argv[3]].decode is effectively attempting to grab a EventFragment and call decode on it

if you look at the ethers.js docs on event fragments theres no method decode and so the script fails https://docs.ethers.io/v5/api/utils/abi/fragments/#EventFragment

i think what we're trying to call is "decodeEventLog" which is a method on ethers.utils.Interface(abi) https://docs.ethers.io/v5/api/utils/abi/interface/

this decodeEventLog requires an EventFragment, the data from the event log and the topics from the event log

this can be achieved with the following code which would replace lines 11-12 in --decode-event

const iface = new ethers.utils.Interface(process.argv[2])
    const events = iface.events;
    
    // keys in events are event signatures ie Withdrawn(address,uint256)
    regex = "^" + process.argv[3] +"\\("

    // From the events list get the mathcing event signature for the given <event-name>
    eventSignature = Object.keys(events).filter((event) => event.match(regex))[0]
    console.log(iface.decodeEventLog(events[eventSignature], JSON.parse(process.argv[4]).data, JSON.parse(process.argv[4]).topics))

heres an example of what this returned for a Withdrawn event log

[
  '0x275445E66B7CD2e7D20937BA3821e8D20b7224f7',
  BigNumber { _hex: '0x3197662e19ad43bb6f', _isBigNumber: true },
  user: '0x275445E66B7CD2e7D20937BA3821e8D20b7224f7',
  amount: BigNumber { _hex: '0x3197662e19ad43bb6f', _isBigNumber: true }
]

Happy to raise a PR against this if you can verify you're seeing the same behaviour, the 2 areas that would probably be improved from the code provided is jq usage saw you guys use jshon but not as familar with how to filter json using that tool so would change that and also remove the hardcoded regex and create the event signature from the abi

also verified --deocde-event is only called in --decode-events in the entire seth folder

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant