Unwrapping an Optional Resource in a post-condition

64 Views Asked by At

I am defining a function in an interface that returns an optional resource and I would like to be able to check if the return value has a certain field by unwrapping it in the post condition.

Here is my code:

pub resource interface Provider {

        pub fun withdrawWithUUID(uuid: UInt64): @AnyResource{NFT}? {
            post {
                result == nil || result!.uuid == uuid: "The uuid of the withdrawn token must be the same as the requested uuid"
            }
            return nil
        }
}

Basically, I am saying that if the result isn't nil, then I want to make sure the withdrawn ID is correct, but I am currently getting an error in the post-condition line that says:

error: value of type `&AnyResource{NonFungibleToken.NFT}?` has no member `uuid`
    --> 179b6b1cb6755e31.NonFungibleToken:145:41
     |
 145 |                 result == nil || result!.uuid == uuid: "The ID of the withdrawn token must be the same as the requested ID"
     |                                          ^^^^ unknown member

I expected the force-unwrap to work in the post-condition, but is that not allowed?

2

There are 2 best solutions below

1
On BEST ANSWER

This sounds like a bug. If you try to do the same within a function, it works correctly.

var value: @AnyResource{NFT}?

var result = &value as &AnyResource{NFT}?

var id = result!.uuid   // works fine

Probably this change (to produce an optionally-typed reference when taking a reference to an optional value) may have not been applied to the internally generated result variable. It seems the result variable still has a reference to an optional type, instead of an optionally-typed reference.

Can you report an issue in the GitHub repo?

1
On

I may be reading this incorrectly, but @{NonFungibleToken.NFT} is not a correct type.

The NonFungibleToken contract interface defines NFT as a resource, not an interface, as seen here:

/// Requirement that all conforming NFT smart contracts have
/// to define a resource called NFT that conforms to INFT
///
pub resource NFT: INFT {
   pub let id: UInt64
}

So you cannot use interface syntax.

Assuming this wasn't the issue, then it is a bug in Cadence.