vyperlang / vyper

Pythonic Smart Contract Language for the EVM
https://vyperlang.org
Other
4.86k stars 793 forks source link

Support Custom Errors #2994

Open skeletor-spaceman opened 2 years ago

skeletor-spaceman commented 2 years ago

Version Information

What's your issue about?

I want to mimic the behavior of custom errors in solidity: https://blog.soliditylang.org/2021/04/21/custom-errors/ Right now I'm just trying to raise an error without parameters, adding parameters would be nice to have.

Should be able to raise bytes4 | Bytes[4] but encountering following errors:

vyper.exceptions.TypeMismatch: Given reference has type Bytes[4], expected String[1024] vyper.exceptions.InvalidType: Expected String[1024] but literal can only be cast as bytes4

Tried all these different options with no success:

    if msg.sender != self.governance: raise keccak256('Governable_OnlyGovernance()')
    if msg.sender != self.governance: raise convert(method_id('Governable_OnlyGovernance()', output_type=Bytes[4]), String[1024]) # Compiler panic
    if msg.sender != self.governance: raise convert(method_id('Governable_OnlyGovernance()'), String[4])
    if msg.sender != self.governance: raise _abi_encode(method_id=method_id('Governable_OnlyGovernance()'))
    if msg.sender != self.governance: raise method_id('Governable_OnlyGovernance()')
    if msg.sender != self.governance: raise 0xe0ae9db4
charles-cooper commented 2 years ago

meeting notes: punt for now as testing frameworks can use other means of error detection. implement if some production smart contracts require handling or issuing of specific custom errors.

charles-cooper commented 2 years ago

idea for how we can export for debugging:

# example: x, y and z are local variables
if x > 10:
  raise  # @error My Custom Error, @trace x,y
  # no runtime reason, tooling should print something like "My Custom Error, x = 11, y = ..."
z80dev commented 2 years ago

Here's a use-case where production smart contracts require issuing of specific custom errors: https://eips.ethereum.org/EIPS/eip-3668

Contracts wishing to support lookup of data from external sources may, instead of returning the data directly, revert using OffchainLookup(address sender, string[] urls, bytes callData, bytes4 callbackFunction, bytes extraData). Clients supporting this specification then make an RPC call to a URL from urls, supplying callData, and getting back an opaque byte string response. Finally, clients call the function specified by callbackFunction on the contract, providing response and extraData. The contract can then decode and verify the returned data using an implementation-specific method.

charles-cooper commented 1 year ago

raw_revert as implemented in https://github.com/vyperlang/vyper/pull/3136 should address this particular use case

pcaversaccio commented 7 months ago

We should consider adding custom errors to .vyi files since they are already part of some EIPs: https://eips.ethereum.org/EIPS/eip-6093.

fubuloubu commented 7 months ago

custom errors is basically a requirement now