Cadence Cookbook

Contribute

Collection for Holding NFTs

Collection for Holding NFTs

14 Oct 2022

Contributed by Flow Blockchain

Beginner

This resource holds your NFTS in a collection in your account.

Smart Contract Example
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 import "NonFungibleToken" access(all) contract Recipe { access(all) resource Collection: NonFungibleToken.Receiver { // Dictionary of NFT conforming tokens // NFT is a resource type with an UInt64 ID field access(all) var ownedNFTs: @{UInt64: {NonFungibleToken.NFT}} // Initialize the NFTs field to an empty collection init() { self.ownedNFTs <- {} } // Withdraw // // Function that removes an NFT from the collection // and moves it to the calling context access(all) fun withdraw(withdrawID: UInt64): @{NonFungibleToken.NFT} { // If the NFT isn't found, the transaction panics and reverts let token <- self.ownedNFTs.remove(key: withdrawID)! return <-token } // Deposit // // Function that takes an NFT as an argument and // adds it to the collection's dictionary access(all) fun deposit(token: @{NonFungibleToken.NFT}) { // Add the new token to the dictionary with a force assignment // If there is already a value at that key, it will fail and revert self.ownedNFTs[token.id] <-! token } // idExists checks to see if an NFT // with the given ID exists in the collection access(all) fun idExists(id: UInt64): Bool { return self.ownedNFTs[id] != nil } // getIDs returns an array of the IDs that are in the collection access(all) fun getIDs(): [UInt64] { return self.ownedNFTs.keys } /// getSupportedNFTTypes returns a dictionary of supported NFT types /// and a boolean indicating if the type is supported access(all) view fun getSupportedNFTTypes(): {Type: Bool} { return {Type<@{NonFungibleToken.NFT}>(): true} } /// isSupportedNFTType checks if the given type is supported /// by the collection access(all) view fun isSupportedNFTType(type: Type): Bool { return type == Type<@{NonFungibleToken.NFT}>() } } }

The Recipe contract defines a resource called Collection that acts as a container for NFTs (Non-Fungible Tokens). The Collection stores NFTs in a dictionary, where each NFT is identified by a unique ID (a UInt64).

The contract provides functions to manage the NFTs in the collection. The withdraw function allows NFTs to be removed from the collection, and the deposit function allows new NFTs to be added. The idExists function checks if an NFT with a specific ID is present in the collection, while the getIDs function returns a list of all the IDs of NFTs currently in the collection. The contract also includes two additional functions, getSupportedNFTTypes and isSupportedNFTType, to determine the types of NFTs the collection supports. These functions are marked as view, meaning they only read data without making changes.

Transaction Example
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 import "NonFungibleToken" import "ExampleNFT" import "MetadataViews" transaction { prepare(signer: auth(Storage, Capabilities) &Account) { // Return early if the account already has a collection if signer.storage.borrow<&ExampleNFT.Collection>(from: ExampleNFT.CollectionStoragePath) != nil { return } // Create a new empty collection let collection <- ExampleNFT.createEmptyCollection() // Save it to the account signer.storage.save(<-collection, to: ExampleNFT.CollectionStoragePath) // Issue a capability for the collection let cap = signer.capabilities.storage.issue<&ExampleNFT.Collection>( ExampleNFT.CollectionStoragePath ) // Publish the capability for public use signer.capabilities.publish(cap, at: ExampleNFT.CollectionPublicPath) } execute { log("Setup account") } }

This transaction script sets up an NFT collection for an account if it doesn't already have one. First, it checks whether the account already has a collection stored at a specific path (ExampleNFT.CollectionStoragePath). If a collection exists, the transaction exits early to avoid duplication. If no collection exists, it creates a new empty collection using the ExampleNFT.createEmptyCollection function. The newly created collection is saved into the account's storage at the specified path.

Next, the script issues a capability for the collection, which allows other accounts or contracts to interact with it securely. This capability is published at a public path (ExampleNFT.CollectionPublicPath), making it accessible to external entities. The transaction completes with a log message indicating that the account setup process is finished.


ProgressNFT Fundamentals

Up Next: Creating Collection For Account

33%


Related Recipes

14 Oct 2022
Mint NFT
Beginner
14 Oct 2022
NFT with Metadata
Beginner
01 Apr 2022
Metadata Views
Beginner