Thanks for the mini-review! Yes, these are the things we hear, explain to folks that it’s a paradigm shift, and they tend to go “oh, yeah that actually makes a lot of sense.” I’m not totally sure how to more get it across in text, so I’m very open to suggestions. Anyhow, in the meantime our standard short rebuttals are below:
In all, this is a noble effort. And I think it is close to a good solution.
Thanks!
No documentation is shown to explain why these codes were chosen.
Fair! You’re right that it should be right in the proposal itself. I’ll copy paste a bunch from the Medium post and the notes from when we did those several dozen company interviews. Thanks
No existing implementations are deployed
In fact, some contracts are already using this (typically in the the security token world). The ERC1400 Security Token proposal depends on it and we have had discussions with folks looking to use it for blockchain identity use cases, as well.
Nibbles
I recommend encouraging ( SHOULD
not MUST
) people to use two-nibble returns hex"01"
in all cases to promote clarity.
I’m confused. In all cases, they’ll get cast to two nibbles, even if the first nibble is 0
, since you can only work with full bytes. Am I misunderstanding something?
It is wasteful in the default case
Yes, but in what way was it successful? This is important information for many use cases that involve automation. Was it successful accepted but will be run later when quorum is reached? Did the transfer go through now? There are lots of cases here.
Adding an additional function return makes this incompatible with every existing contract and other standard, including ERC-20 and ERC-721.
Good news! You don’t need to change those contracts to wrap them in an interface (in a proxy contract), effectively giving backwards compatibility for those that already rely on ERC20 or ERC721, but giving a separate interface for others. Future contracts can make use of this functionality.
But I should emphasize that this proposal was created to solve problems that we were having when developing security tokens, and enables new use cases that are currently difficult to do interoperatively on Ethereum. Calling ERC20s and NFTs directly as is most commonly done today (largely because of how difficult it is to communicate between contracts autonomously) is not an amazing use case to show off this design pattern.
It is unsafe
As per the EIP, this is in no way a replacement for revert! Exceptional, state-breaking, or dangerous cases should absolutely 100% revert! In fact, the library provides helper functions to aid with a number of revert scenarios!
The async DEX examples are not realistic
Yes, it’s true that today’s DEXes aren’t very smart. They could be smarter and more autonomous by using such a standard, but still IMO doing one on-chain is impractical for most scenarios. And fair, it’s not the greatest use case, but it’s short, and people in the ecosystem understand token-related flows today. Essentially it’s a toy example for illustrating how codes can flow through a system, as per HTTP or BEAM. If you can think of a better example that’s widely understandable to an audience with experience limited to Solidity and JS (and that shockingly often doesn’t fully understand HTTP), I would love to include it!
Codes are ill-defined
Should I return 0xE1
Decrypt Success or 0x01
Success or 0x21
Found?
I mean, it depends on your use case. If you decrypted something, you should use 0xE1
, if you looked something up in a table or found something you should use 0x21
, and if you want straight dumb compatibility with bools you should use 0x01
. HTTP Status Codes have a similar range of more specific codes to help in control flow.
They should have well-defined meanings, including motivations
These are all taken from real-world scenarios from interviews that we did with Ethereum companies, so there are motivations for every code (some cases joined or abstracted), even if they’re not all spelled out. As always with code, we think more documentation and use cases will be useful.
Please consider to update this proposal to only use status codes through reverts.
Evidently the paradigm and purpose of this document is not clear enough at the moment, for which I apologize. I do wonder if people come to this EIP with preexisting assumptions, since (as mentioned before) when I spell it out in detail that “no it doesn’t work like that and isn’t written in that way anywhere”, a light bulb goes off for a lot of people. It’s purpose is to give more semantic information to other contracts, developers, and users, in an automated way, in a similar vein to HTTP status codes. It is not about propagating exceptions: it’s about sending context around for both success and failure, and true errors/exceptional cases should promptly exist this flow and revert.
I’ll give you a simple illustrative real-world example for status codes:
You need to check if someone is 1/n whitelists maintained by several parties. This is key in regulated scenarios, so that not every token has to (for example) check everyone’s photo ID separately, which is time consuming, expensive, and error prone, and does not easily work across borders without multiple domain experts handling this per-domicile.
Since you need to check several of these lists, you need to not revert if it fails, and it’s not an irrecoverable error, it’s a normal part of flow (chances are that you’ll need to check several of these lists). You may not be allowed to read from this list (a closed list), the user being checked may be actively blacklisted, they may not be on that list, or their verification has started off-chain (someone is reviewing their passport) but hasn’t completed. If you need 2/3 to succeed, and 2 have blocking codes (ie: even numbered codes), then you should revert
. Likewise, if there is an overflow, it should also revert.
AND that makes it compatible with another proposal — EIP 838: ABI specification for REVERT reason string · Issue #838 · ethereum/EIPs · GitHub
As per the EIP text, this is already fully compatible with revert-with-reason, and the helper lib provides ways of bridging the two with a nice, semantic interface.
Thanks again for the review Looking forward to further feedback on the above responses!
Relevant Resources