3

I want to find out how exactly "revert" works in ink! smart contracts:

  1. What happen if we panic!() in ink! contracts? IIRC we shouldn't use panic!() in runtime.
  2. Is there any difference between panic!() and returning Result::Error in ink! contracts?
  3. I don't find any documentation regarding this. Am I missing something? Can anybody give me a link.

2 Answers 2

8
  1. panic! reverts the state but it also ends the execution of the current contract call. If your method was called by another contract, that contract will receive a CalleeTrapped error instead of the Result. If that method was called by the user, then he will receive ContractTrapped.

  2. Result can contain more descriptive errors than CalleeTrapped. The Result can be handled by the caller contract or can be shown better on the UI side. CalleeTrapped means that something was wrong during execution.

  3. Returning the Result means that the code was executed predictable way. The language(ink! or ask!) encodes the Result into bytes and returns it back to the caller. If the result was an error, the code raises the REVERT flag at the end of the execution so the state will be reverted(That means that revert of state was initiated by the callee contract). On the caller side, the code decoded the bytes into Result and provided a descriptive error.

    If panic! or assert! was called that ends the execution of the contract immediately. And it is CalleeTrapped on contract-pallet level. contract-pallet reverts the state because the contract failed. That error is returned to the caller.

    More about it you can read in the discussion.

3
  • As I check in paritytech.github.io/ink/ink_env/enum.Error.html. There are ContractReverted, CalleeReverted. Should developers have an eye on them?
    – Daniel Lam
    May 4, 2022 at 16:12
  • CalleeReverted is used during the checking of execution result. If it is reverted we will try to decode the output into the expected type(like Result). May 4, 2022 at 19:02
  • 1
    Ok Now I understand the difference between the Trapped and Reverted variant. Actually, they follow the same semantics of panic!() and Result in Rust. For new readers, this is what I mean. When you receive the Trapped, the error can be expected (because you intentionally panic!() in your contract) or unexpected (because the code you don't control panic!()). But overall, we should treat this as unexpected error When you receive the Reverted, this means that your contract handle the error smoothly and it's part of business logic. So the error for this case is expected.
    – Daniel Lam
    May 5, 2022 at 5:48
3

The difference is whether you want to encode additional information for the caller in case of an error happening. In both cases all state is reverted.

If you panic (no matter through which means you emit the panic) then no output is emitted. Pretty logical as there is no way to return anything in case of a panic. Please note that the panic message is written to the debug buffer in case of a debug-contract and can be read by an RPC client during a dry run.

If you return a Result::Err from your message then all state is reverted but the the caller decode this Result::Err and act on it.

It is important to understand panics between cross contract calls are caught by default. The panic of a callee is returned as an error (CalleeTrapped) to the caller and doesn't bubble up by default. So both errors are hand-able. Panics just don't convey any information to the caller about the reason for the error.

4
  • Usually, we use custom error for our contract. But as you said, we may also receive CalleeTrapped as Result::Err also. So how do we combine that system error with the custom error of the contract in the function signature ` -> Result<>`. Thanks @Alexander
    – Daniel Lam
    May 6, 2022 at 6:22
  • You don't receive CallTrapped if you return Result::Err. Only when you trap. May 6, 2022 at 6:52
  • Sorry but what I mean is that is there any example that handle two cases CallTrapped and Result::Err for a cross-contract call. This is important because from the caller perspective, we never know what the callee will return. Thanks
    – Daniel Lam
    May 6, 2022 at 8:42
  • 1
    I found the github issue of this. github.com/paritytech/ink/issues/1207. Thanks
    – Daniel Lam
    May 6, 2022 at 14:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.