1

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 Answers2

3

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?

Supun Setunga
  • 314
  • 1
  • 4
0

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.

Jacob Tucker
  • 132
  • 7
  • I'm working on the v2 versions of the contract standards, where `NonFungibleToken.NFT` is a resource interface. You can see what I'm working on here: https://github.com/onflow/flow-nft/pull/126 – Joshua Hannan Apr 15 '23 at 03:36