umbracle/ethgo

ParseMethodSignature not working for tuples

Closed this issue · 8 comments

Current behavior
Passing a method signature such with complex usage of tuples such as multipleTransfer((address,(uint256,address)[])) (which is equal to multipleTransfer(tuple(address,tuple(uint256,address)[])) fails

Expected behavior
Using NewMethod(multipleTransfer("(address,(uint256,address)[])")) should succeed in parsing the method signature into a valid Method with the correct inputs as tuple.

Hello.

Does multipleTransfer(tuple(address,tuple(uint256,address)[])) works?

No it sadly does not. This feature is not necessarily needed as I see it too complex and the best way to create a new Method should be through the usage of the complete ABI of that method and not only the method signature.

But if it is possible to create a Method struct with only the method signature deterministically, that would be really powerful and useful (for example, you won't need the ABI to be able to communicate with a contract but only the method signature would be enough)

I understand, something like this is available https://github.com/umbracle/go-web3/blob/master/abi/abi_test.go#L53 but it will not work if the input is a struct (I think). In ethers.js it does work with tuples. I can work to fix this over the weekend since I have to do a couple more changes on abi .json decoding.

Thanks! Just be aware that this multipleTransfer(tuple(address,tuple(uint256,address)[])) is not a valid method signature. The tuple keyword should not be part of the signature. If you encounter a parenthesis "inside" of the method signature (first parenthesis), I think you can assume it's a tuple.

Ok, but I do not think there any difference with what ethers.js decodes here right? I will just try to implement those test cases.

I have a fix in #134. It turns out it was already supported but the regexp expression to get the function parameters was not correct to counter for extra '('. I will merge this after your #131.

Please test the branch #134 with the changes, note that you need to use function multipleTransfer(tuple(address,tuple(uint256,address)[])) with the function prefix and tuple().

Sadly that is not useful for our use case because using tuple in the method signature is not valid. One of the use case of this method is to be able to pass a method signature and get a Method back so arguments can be encoded without needing the whole ABI.

You should be able to do something like:

abi := web3.NewABI(myABI)
method := web3.ParseMethodSignature(abi.Methods[0].Sig())
txData := web3.Encode(method.Inputs, args)

where abi.Methods[0].Sig() is the method signature multipleTransfer((address,(uint256,address)[]))

Would that work ?