-
Notifications
You must be signed in to change notification settings - Fork 45
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
Abiv2 #468
Conversation
I don't fully understand the issue (I checked out the code but couldn't find concrete errors). Tokenizable requires two methods: Tokenize requires one method: What I don't understand is how you would be able to implement |
Probably not worth your time to investigate too deeply, Felix. I was mostly thinking out loud in case @nlordell had encountered this before. Will try to explain it again: |
This rings a bell. I think this is why I abandoned implementing this a while back. I think the issue is that the |
I am working on a PR for web3 that would fix this but it has to introduce some breakage there. Until that is merged (if ever) we should be able to duplicate the same trait changes into ethcontractract because we manually call ethabi::encode / decode anyway without going through web3 for that, so we don't have to use the same trait to create Tokens as web3 does. |
c55b5bf
to
3c4da15
Compare
I've moved the tokenizaton related traits from rust-web3 into ethcontract. This makes them simpler (than the rust-web3 version) because ethcontract uses them for fewer purposes than rust-web3 and gives us more control over them. I feel this is what we should do mid-term until we see the route web3 and ethabi take. Still WIP because I need to add error handling, documentation and more tests for abi v2. |
fca1192
to
404b73b
Compare
This is ready for review now. PR is big but I don't see a way to split this into semantically useful parts. 80% of the changes are the new file You can see the change I had to make to ethabi here https://github.com/vkgnosis/ethabi/commits/ethcontract . |
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.
Just some comments, as I'm still not sure I fully understand what's going on. Leaving the thorough review up to @nlordell
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.
In general, the code looks good.
I still haven't wrapped my head around the SingleTokenize
and MultiTokenize
traits. I'm going to take a second look with fresh eyes on Monday.
I found an old PR for adding support for decoding nested tuples: |
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.
Code looks good to me.
It might be worth exploring whether the MultiTokenize
can just be represented by a SingleTokenize
that always returns a tuple, this way we have one less trait.
I think the distinction was important in web3
prior to ABI v2 as function parameters are kind of like a tuple, but nested tuples weren't allowed, but since this is no longer the case, we might get away with a single trait.
Added two new commits that simplify the code by removing MultiTokenize and Return. It turns out we can represent both cases as SingleTokenize tuples. |
The one remaining point is what to do about the ethabi fork. As Nick pointed out we can't use the git dependency because it would prevent ethcontract from being publishes to crates.io. I think a reasonable short term fix is if I publish a version of my fork so we can have it as a crates.io dependency. Long term we can still depends on the original ethabi crate. |
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.
Amazing! I think it turned out really good!
@nlordell FYI I had to add another small commit (the most recent one) here for a problem I discovered when using this branch in v2-services. It's a minor change and I am probably going to merge this PR tomorrow. |
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.
Changes look fine to me.
We use a fork of ethabi that has patches applied so that it in turn supports abi v2. Once the mainline ethabi gets updated we can switch back to it. We move tokenization related traits from rust-web3 into ethcontract because rust the web3 version does not support tokenizing tuples and because this gives us more control over the traits. This commit is technically a breaking change because we touch some parts of the public interface like the error enum but for most users nothing should change. Abi v2 functions are tested in the `abi` example. Some events there had to be changed to give names to the parameters because of yet unfixed bug in ethabi where it addresses the parameters based on a map of their name which leads it to use a copy of one of tokens for all of the parameters. This bug is already present in the current version of ethabi but now throws errors in the example because of stricter verification of the size of integer parameters.
Edit: Ready for review, scroll down for update.
Nick pointed out that there is an ethabi fork that already supports abiv2. This PR is using this.
Where I am currently stuck is on the tokenization for web3. Web3 has several related traits https://docs.rs/web3/0.15.0/web3/contract/tokens/index.html . The trait that is usually accepted and used by ethcontract is
Tokenize
.In my solidity example we have
In the abi this becomes
Tuple(uint8, uint16)
which gets turned by ethcontract in this PR intos : (u8, u16)
.Web3 has one trait
Tokenizable
for things that can get turned into a singleToken
and another traitTokenize
that turns things intoVec<Token>
. The latter is implemented probably for convenience so that users of web3 can pass tuples of different tokenziable things to it. This has now become problematic because it prevents tuples of Tokenizable to themself implement Tokenizable (by turning into Token::Tuple) because of ambiguous implementations. Imo the correct way to fix this is to get rid of the Tokenize trait so that we can have the mentioned tuple impl. This involves getting this merged in web3 first.I am not sure if there is a way to achieve the same thing without touching web3. The only alternative I see is to duplicate Tokenize into ethcontract and implemented it correctly for tuples and then pass our Tokenize around instead of web3's.