-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
Function input decoder #991
Conversation
914c7c2
to
d21e838
Compare
fbece10
to
122b592
Compare
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.
Thanks for adding docs and tests right up front!
It's a nice, simple implementation 👍
It's also worth thinking about what should happen during a function selector hash collision.
Most importantly, there are probably some other types worth testing. I added a test example of addresses, which should be returned checksummed, and strings which should be returned as type str
.
One approach to solving the address checksum and string tests would be to use map_abi_data()
with BASE_RETURN_NORMALIZERS
.
I also added the round-trip test (that you can re-generate the transaction data by reusing the method and arguments).
docs/contracts.rst
Outdated
|
||
.. py:classmethod:: Contract.decode_function_input(data) | ||
|
||
Decodes function input data and returns :py:class:`ContractFunction` and decoded parameters as :py:class:`dict`. |
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.
This could be a little clearer to newbies that we're talking about the data
field of a transaction. Something like:
Decodes the transaction data used to invoke a smart contract function, and returns...
docs/contracts.rst
Outdated
.. code-block:: python | ||
|
||
>>> data = '338b5dea00000000000000000000000042d6622dece394b54999fbd73d108123806f6a180000000000000000000000000000000000000000000000000000000000000032' | ||
>>> contract.decode_function_input(data) |
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.
The example code could drive the point home with:
>>> transaction = w3.eth.getTransaction(...)
>>> transaction.data
'338b5dea00000000000000000000000042d6622dece394b54999fbd73d108123806f6a180000000000000000000000000000000000000000000000000000000000000032'
>>> contract.decode_function_input(transaction.data)
docs/contracts.rst
Outdated
>>> data = '338b5dea00000000000000000000000042d6622dece394b54999fbd73d108123806f6a180000000000000000000000000000000000000000000000000000000000000032' | ||
>>> contract.decode_function_input(data) | ||
(<Function depositToken(address,uint256)>, | ||
{'token': '0x42d6622dece394b54999fbd73d108123806f6a18', 'amount': 50}) |
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.
The official docs aren't a good place to advertise a live token (even subtly). :)
Something like ENS (no one profiting) or TheDAO (not live) could be good.
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.
ENS example actually sounds great, I'll update the docs.
'0xf0fdf8340000000000000000000000000000000000000000000000000000000000000001', | ||
'a', | ||
[1], | ||
{'': 1}, |
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.
These expected values would be easier to read if the input arguments were named descriptively, like {'intarg': 1}
.
Side note: I am even wondering if we should throw a validation error on an ABI with an empty variable name -- it would probably cause problems elsewhere (not suggesting adding that to this PR).
), | ||
), | ||
) | ||
def test_contract_abi_decoding(web3, abi, data, method, arguments, expected): |
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.
Do you want to add a test against arguments
? It's currently unused. Maybe it can just be dropped.
5c6c400
to
2cf7c34
Compare
Thanks for pointing out the normalizers feature and adding the tests for additional data types. I updated the code, so now all the tests pass. I also updated the wording in documentation and replaced the example with the infamous The DAO transaction. |
Unrelated test failure: occasionally parity integration tests are flaky. |
Very nice, thanks for the contribution! |
What was wrong?
There was no trivial method to decode function input parameters.
How was it fixed?
This adds
Contract.decode_function_input
which is a counterpart toContract.encodeABI
.Works like a charm ✨
Cute Animal Picture