-
-
Notifications
You must be signed in to change notification settings - Fork 811
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
Structs as args #1115
Structs as args #1115
Conversation
6664b38
to
881db2b
Compare
Is emitting a struct in an event possible? |
Not in this PR. I think that structs in events needs a bit more thought. Since each byte costs 8 gas, we probably should use the packed ABI encoding. I'm not sure what solidity produces / what web3 expects. |
Moved that convo to #1170 |
c250d1e
to
d1c78a3
Compare
Ok, based on the latest meeting, I rebased this PR and reduced the scope. For now, nested structs will not work with the ABI, and neither will struct arguments. Also, I opted to disallow passing structs with dynamic members for now, otherwise this PR will get too large. Should be ready for review (pending CI)! |
CI failed, but I also think this feature needs way more tests lol |
Also, can you add issues to track what was deemed out of scope? |
@fubuloubu I can add some typechecking tests. Any other specific tests you think should be in here? |
Anything with the ABI should be pretty throughly tested. That boundary a lot of things can go wrong haha. |
@jacqueswww when merged, can you cut as 0.1.0b7? |
@fubuloubu I want a few more bug fixes in first, but b7 will be soon. In the meantime just peg the commit hash in your requirements. |
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.
LGTM, this is great addition to vyper! :) @charles-cooper I think the one test that this still needs is if one wants to use a struct in an extract contract
interface?
Testing this. It compiles, but I'm having difficulties getting the ABI to work with Web3py. What's the best way to do this? File: https://github.com/GunClear/plasma-cash-vyper/blob/struct-args/contracts/RootChain.vy |
@fubuloubu I don't think web3py is ready for those types of nested tuples (yet). |
v5 has v2 outputs the struct definitions right? |
I think I will just merge this for now - as I am scared of branches diverging too much. Will create a ticket for the outstanding test. |
Follow-up: ABI v2 doesn't seem to work with this :( |
@fubuloubu uh oh! Can you provide a reproducible case? |
dependencies: >>> import vyper
>>> from web3 import Web3, EthereumTesterProvider
>>> w3 = Web3(EthereumTesterProvider())
>>> interface = vyper.compile_code("""
... struct MyStruct:
... a: address
... b: bytes32
...
... @public
... def a(s: MyStruct) -> address:
... return s.a
...
... @public
... def b(s: MyStruct) -> bytes32:
... return s.b
... """, output_formats=['abi', 'bytecode', 'bytecode_runtime'])
>>> txn_hash = w3.eth.contract(**interface).constructor().transact()
>>> address = w3.eth.waitForTransactionReceipt(txn_hash)['contractAddress']
>>> contract = w3.eth.contract(address, **interface)
>>> contract.functions.a(contract.address, b'\x00' * 32).call()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/bryant/.pyenv/versions/test/lib/python3.6/site-packages/web3/contract.py", line 1003, in __call__
clone._set_function_info()
File "/home/bryant/.pyenv/versions/test/lib/python3.6/site-packages/web3/contract.py", line 1012, in _set_function_info
self.kwargs
File "/home/bryant/.pyenv/versions/test/lib/python3.6/site-packages/web3/_utils/contracts.py", line 128, in find_matching_fn_abi
raise ValidationError(message)
web3.exceptions.ValidationError:
Could not identify the intended function with name `a`, positional argument(s) of type `(<class 'str'>, <class 'bytes'>)` and keyword argument(s) of type `{}`.
Found 1 function(s) with the name `a`: ['a((address,bytes32))']
Function invocation failed due to improper number of arguments.
>>> contract.functions.a((contract.address, b'\x00' * 32)).call()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/bryant/.pyenv/versions/test/lib/python3.6/site-packages/web3/contract.py", line 1003, in __call__
clone._set_function_info()
File "/home/bryant/.pyenv/versions/test/lib/python3.6/site-packages/web3/contract.py", line 1012, in _set_function_info
self.kwargs
File "/home/bryant/.pyenv/versions/test/lib/python3.6/site-packages/web3/_utils/contracts.py", line 97, in find_matching_fn_abi
function_candidates = pipe(abi, *filters)
File "cytoolz/functoolz.pyx", line 589, in cytoolz.functoolz.pipe
File "cytoolz/functoolz.pyx", line 565, in cytoolz.functoolz.c_pipe
File "/home/bryant/.pyenv/versions/test/lib/python3.6/site-packages/web3/_utils/abi.py", line 203, in filter_by_encodability
in contract_abi
File "/home/bryant/.pyenv/versions/test/lib/python3.6/site-packages/web3/_utils/abi.py", line 204, in <listcomp>
if check_if_arguments_can_be_encoded(function_abi, args, kwargs)
File "/home/bryant/.pyenv/versions/test/lib/python3.6/site-packages/web3/_utils/abi.py", line 221, in check_if_arguments_can_be_encoded
for _type, arg in zip(types, arguments)
File "/home/bryant/.pyenv/versions/test/lib/python3.6/site-packages/web3/_utils/abi.py", line 221, in <genexpr>
for _type, arg in zip(types, arguments)
File "/home/bryant/.pyenv/versions/test/lib/python3.6/site-packages/web3/_utils/abi.py", line 166, in is_encodable
base, sub, arrlist = process_type(_type)
File "/home/bryant/.pyenv/versions/test/lib/python3.6/site-packages/web3/_utils/abi.py", line 136, in process_type
type_str_repr,
ValueError: Cannot process type '(address,bytes32)': tuple types not supported |
@fubuloubu that looks like a bug. Could you please create an issue? |
A think it's a bug against web3py v5 if it doesn't implement the full abi V2 spec yet. How did you decide what the ABI output should be in moving forward with this PR? Basically follow Solidity? |
@fubuloubu Oh that's right. I even said so in my comments above (and apparently promptly forgot!) To answer your question, I wanted to follow Solidity but tuples are not supported by eth-abi yet. The signature should be ABI-encoded as
and something similar for outputs. But that doesn't work, so for now I kept the input/output encoding the same as before (tuple inputs are encoded as |
I really wished the ABI had entries for structs, so we can just reference structs in different places instead of this tuple nonsense lol |
- What I did
Partially implement #1019 - structs as arguments and return values.
WIP Checklist
- How I did it
Add packing / unpacking code for structs
- How to verify it
See tests
- Description for the changelog
Ability to pass structs as args and return values. Structs which contain other structs or structs which contain bytearrays not supported.