github.com/DapperCollectives/CAST/backend@v0.0.0-20230921221157-1350c8be7c96/main/cadence/contracts/NonFungibleToken.cdc (about)

     1  /**
     2  
     3  ## The Flow Non-Fungible Token standard
     4  
     5  ## `NonFungibleToken` contract interface
     6  
     7  The interface that all non-fungible token contracts could conform to.
     8  If a user wants to deploy a new nft contract, their contract would need
     9  to implement the NonFungibleToken interface.
    10  
    11  Their contract would have to follow all the rules and naming
    12  that the interface specifies.
    13  
    14  ## `NFT` resource
    15  
    16  The core resource type that represents an NFT in the smart contract.
    17  
    18  ## `Collection` Resource
    19  
    20  The resource that stores a user's NFT collection.
    21  It includes a few functions to allow the owner to easily
    22  move tokens in and out of the collection.
    23  
    24  ## `Provider` and `Receiver` resource interfaces
    25  
    26  These interfaces declare functions with some pre and post conditions
    27  that require the Collection to follow certain naming and behavior standards.
    28  
    29  They are separate because it gives the user the ability to share a reference
    30  to their Collection that only exposes the fields and functions in one or more
    31  of the interfaces. It also gives users the ability to make custom resources
    32  that implement these interfaces to do various things with the tokens.
    33  
    34  By using resources and interfaces, users of NFT smart contracts can send
    35  and receive tokens peer-to-peer, without having to interact with a central ledger
    36  smart contract.
    37  
    38  To send an NFT to another user, a user would simply withdraw the NFT
    39  from their Collection, then call the deposit function on another user's
    40  Collection to complete the transfer.
    41  
    42  */
    43  
    44  // The main NFT contract interface. Other NFT contracts will
    45  // import and implement this interface
    46  //
    47  pub contract interface NonFungibleToken {
    48  
    49      // The total number of tokens of this type in existence
    50      pub var totalSupply: UInt64
    51  
    52      // Event that emitted when the NFT contract is initialized
    53      //
    54      pub event ContractInitialized()
    55  
    56      // Event that is emitted when a token is withdrawn,
    57      // indicating the owner of the collection that it was withdrawn from.
    58      //
    59      // If the collection is not in an account's storage, `from` will be `nil`.
    60      //
    61      pub event Withdraw(id: UInt64, from: Address?)
    62  
    63      // Event that emitted when a token is deposited to a collection.
    64      //
    65      // It indicates the owner of the collection that it was deposited to.
    66      //
    67      pub event Deposit(id: UInt64, to: Address?)
    68  
    69      // Interface that the NFTs have to conform to
    70      //
    71      pub resource interface INFT {
    72          // The unique ID that each NFT has
    73          pub let id: UInt64
    74      }
    75  
    76      // Requirement that all conforming NFT smart contracts have
    77      // to define a resource called NFT that conforms to INFT
    78      pub resource NFT: INFT {
    79          pub let id: UInt64
    80      }
    81  
    82      // Interface to mediate withdraws from the Collection
    83      //
    84      pub resource interface Provider {
    85          // withdraw removes an NFT from the collection and moves it to the caller
    86          pub fun withdraw(withdrawID: UInt64): @NFT {
    87              post {
    88                  result.id == withdrawID: "The ID of the withdrawn token must be the same as the requested ID"
    89              }
    90          }
    91      }
    92  
    93      // Interface to mediate deposits to the Collection
    94      //
    95      pub resource interface Receiver {
    96  
    97          // deposit takes an NFT as an argument and adds it to the Collection
    98          //
    99          pub fun deposit(token: @NFT)
   100      }
   101  
   102      // Interface that an account would commonly 
   103      // publish for their collection
   104      pub resource interface CollectionPublic {
   105          pub fun deposit(token: @NFT)
   106          pub fun getIDs(): [UInt64]
   107          pub fun borrowNFT(id: UInt64): &NFT
   108      }
   109  
   110      // Requirement for the the concrete resource type
   111      // to be declared in the implementing contract
   112      //
   113      pub resource Collection: Provider, Receiver, CollectionPublic {
   114  
   115          // Dictionary to hold the NFTs in the Collection
   116          pub var ownedNFTs: @{UInt64: NFT}
   117  
   118          // withdraw removes an NFT from the collection and moves it to the caller
   119          pub fun withdraw(withdrawID: UInt64): @NFT
   120  
   121          // deposit takes a NFT and adds it to the collections dictionary
   122          // and adds the ID to the id array
   123          pub fun deposit(token: @NFT)
   124  
   125          // getIDs returns an array of the IDs that are in the collection
   126          pub fun getIDs(): [UInt64]
   127  
   128          // Returns a borrowed reference to an NFT in the collection
   129          // so that the caller can read data and call methods from it
   130          pub fun borrowNFT(id: UInt64): &NFT {
   131              pre {
   132                  self.ownedNFTs[id] != nil: "NFT does not exist in the collection!"
   133              }
   134          }
   135      }
   136  
   137      // createEmptyCollection creates an empty Collection
   138      // and returns it to the caller so that they can own NFTs
   139      pub fun createEmptyCollection(): @Collection {
   140          post {
   141              result.getIDs().length == 0: "The created collection must be empty!"
   142          }
   143      }
   144  }