onflow / cadence

Cadence, the resource-oriented smart contract programming language 🏃‍♂️
https://developers.flow.com/cadence
Apache License 2.0
532 stars 139 forks source link

Type Walking #1092

Open rheaplex opened 3 years ago

rheaplex commented 3 years ago

Given a standard NonFungibleToken standard contract that implements the contract-level interface, and the NFT and Collection resources, it would be useful to be able to check the type of instances of related objects at runtime.

This would work as follows:

pub fun StoreDetails(nft: @{NonFungibleToken.INFT}, collection: &{NonFungibleToken.CollectionPublic}) {
  let nftContract: Type = nft.getType().getContractType()
  let collectionContract: Type = collection.getType().getContractType()
  assert(nftContract == collectionContract, message: "token is not of same type as collection")
...

and/or:

pub fun StoreDetails(nft: @{NonFungibleToken.INFT}, collection: &{NonFungibleToken.CollectionPublic}) {
  assert(nft.isInSameContract(collection), message: "token is not of same type as collection")
...

and/or:

pub fun StoreDetails(nft: @{NonFungibleToken.INFT}, collection: &{NonFungibleToken.CollectionPublic}) {
  let nftContract: Type = nft.getType().getContractType()
  let collectiontype: Type = nftContract.getImplementations<NonFungibleToken.CollectionPublic>()[0]
  assert(nftContract == collectionContract, message: "token is not of same type as collection")
...

This would allow more robust runtime checking of capabilities that are meant to be of related types in the nftStorefront, and elsewhere where this is desirable.

turbolent commented 3 years ago

Good idea. I would generalize this from "contract type" to "parent type", and make the result optional, as not every type has a parent type

bluesign commented 3 years ago

@turbolent or maybe something like getLocation() or just.location ?

dete commented 2 years ago

@rheaplex: Curious to get your thought on this pattern:

assert(nft.getType() == collection.nftType())

Or

assert(collection.supportsNftType(nft.getType()))

Seems like that is more flexible and can be implemented without language changes...