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

abigen! generates incorrect types for functions as arguments #1699

Open
tomtau opened this issue Sep 15, 2022 · 4 comments
Open

abigen! generates incorrect types for functions as arguments #1699

tomtau opened this issue Sep 15, 2022 · 4 comments
Labels
bug Something isn't working

Comments

@tomtau
Copy link
Contributor

tomtau commented Sep 15, 2022

Version
0.17
Platform
macOS 12
Description
The generated method will have u8 as the type for the function, but according to https://docs.soliditylang.org/en/develop/abi-spec.html#types

function: an address (20 bytes) followed by a function selector (4 bytes). Encoded identical to bytes24.

Example ABI snippet:

	{
		"inputs": [
			{
				"internalType": "uint256[]",
				"name": "r",
				"type": "uint256[]"
			},
			{
				"internalType": "function (uint256) pure external returns (uint256)",
				"name": "f",
				"type": "function"
			}
		],
		"name": "map",
...

Example corresponding currently generated function by abigen!:

pub fn map(&self, r: ::std::vec::Vec<ethers::core::types::U256>, f: u8) -> ethers::contract::builders::ContractCall<M, ...>

Ideally, this should generate correct raw types or take a high-level type that will e.g. resolve the provided contract address+function name to the corresponding bytes24 argument.

@tomtau tomtau added the bug Something isn't working label Sep 15, 2022
@gakonst
Copy link
Owner

gakonst commented Sep 15, 2022

How are you calling this client side? I wouldn't expect a function that takes a function pointer to be exposed to the client?

@mattsse
Copy link
Collaborator

mattsse commented Sep 15, 2022

also raised here rust-ethereum/ethabi#273

there's currently no native support for Function types.

we could work around this by tracking function inputs separately. Similar to the existing workarounds that we're using to resolve all structs.

is definitely doable

@gakonst
Copy link
Owner

gakonst commented Sep 15, 2022

But how are you supposed to call this from Rust? Can you pass it a Function type?

@mattsse
Copy link
Collaborator

mattsse commented Sep 15, 2022

function: an address (20 bytes) followed by a function selector (4 bytes). Encoded identical to bytes24.

I think a function argument is something like a callback.

Something like this is possible:

contract Callback {

  Request[] requests;

  struct Request {
    bytes data;
    function(bytes memory) external callback;
  

  function request(bytes memory data, function(bytes memory) external callback) public {
    requests.push(Request(data, callback));
  }

  function reply(uint256 id, bytes memory response) public {
    requests[id].callback(response);
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants