Cadence Cookbook

Contribute

Creating Collection For Account

Creating Collection For Account

14 Oct 2022

Contributed by Flow Blockchain

Beginner

Create a new collection for an existing Flow account that doesn't have one so that it can store your NFTS in it.

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 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 /// ExampleNFT.cdc /// /// This is a complete version of the ExampleNFT contract /// that includes withdraw and deposit functionalities, as well as a /// collection resource that can be used to bundle NFTs together. /// /// Learn more about non-fungible tokens in this tutorial: https://developers.flow.com/cadence/tutorial/non-fungible-tokens-1 access(all) contract ExampleNFT { // Declare Path constants access(all) let CollectionStoragePath: StoragePath access(all) let CollectionPublicPath: PublicPath access(all) let MinterStoragePath: StoragePath // Tracks the unique IDs of the NFTs access(all) var idCount: UInt64 access(all) resource NFT { access(all) let id: UInt64 init(initID: UInt64) { self.id = initID } } access(all) entitlement Withdraw // Interface defining required methods for the Collection access(all) resource interface CollectionInterface { access(all) fun deposit(token: @NFT) access(Withdraw) fun withdraw(withdrawID: UInt64): @NFT access(all) view fun getIDs(): [UInt64] } // Collection resource conforming to CollectionInterface access(all) resource Collection: CollectionInterface { access(all) var ownedNFTs: @{UInt64: NFT} init () { self.ownedNFTs <- {} } access(Withdraw) fun withdraw(withdrawID: UInt64): @NFT { let token <- self.ownedNFTs.remove(key: withdrawID) ?? panic("Could not withdraw NFT with id=".concat(withdrawID.toString())) return <-token } access(all) fun deposit(token: @NFT) { self.ownedNFTs[token.id] <-! token } access(all) view fun getIDs(): [UInt64] { return self.ownedNFTs.keys } } access(all) fun createEmptyCollection(): @Collection { return <- create Collection() } access(all) fun mintNFT(): @NFT { let newNFT <- create NFT(initID: self.idCount) self.idCount = self.idCount + 1 return <-newNFT } init() { self.CollectionStoragePath = /storage/nftTutorialCollection self.CollectionPublicPath = /public/nftTutorialCollection self.MinterStoragePath = /storage/nftTutorialMinter self.idCount = 1 self.account.storage.save(<-self.createEmptyCollection(), to: self.CollectionStoragePath) let cap = self.account.capabilities.storage.issue<&Collection>(self.CollectionStoragePath) self.account.capabilities.publish(cap, at: self.CollectionPublicPath) } }

The createEmptyCollection function is part of the ExampleNFT contract and is used to create a new, empty collection for an account. A collection is a resource that allows users to store and manage their non-fungible tokens (NFTs) by bundling them together.

When invoked, the createEmptyCollection function creates a new instance of the Collection resource. This resource is initialized with an empty set of NFTs. The collection resource adheres to the CollectionInterface, which defines methods for depositing NFTs, withdrawing NFTs by their ID, and viewing the list of owned NFT IDs.

Once the collection is created, it is returned as a resource, which can then be stored in the account's private storage using a transaction. This enables the account to manage NFTs directly. Additionally, the function creates a public capability for the collection, which grants others access to the functionality provided by the collection (e.g., depositing and withdrawing NFTs) through the CollectionPublic interface.

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 31 32 33 34 35 36 37 import "NonFungibleToken" import "ExampleNFT" import "MetadataViews" // This transaction is what an account would run // to set itself up to receive NFTs transaction { prepare(signer: auth(Storage, Capabilities) &Account) { // Check if the account already has a collection let collectionRef = signer.storage.borrow<&ExampleNFT.Collection>(from: ExampleNFT.CollectionStoragePath) // If a collection already exists, return early if collectionRef != nil { return } // Create a new empty collection let collection <- ExampleNFT.createEmptyCollection() // Save it to the account storage signer.storage.save(<-collection, to: ExampleNFT.CollectionStoragePath) // Create a capability for the collection let collectionCap = signer.capabilities.storage.issue<&{NonFungibleToken.CollectionPublic}>( ExampleNFT.CollectionStoragePath ) // Publish the capability signer.capabilities.publish(collectionCap, at: ExampleNFT.CollectionPublicPath) } execute { log("Setup account") } }

This transaction demonstrates how to create a new empty collection for an account and save it as a resource in the user's storage. Initially, the transaction checks if the account already has a collection. If one doesn't exist, it proceeds to create a new ExampleNFT.Collection and stores it in the account’s storage under a specified path.

After saving the collection, the transaction creates a public capability for the collection. This capability allows others to interact with the collection by providing access to specific functions defined in the NonFungibleToken.CollectionPublic interface, such as viewing or transferring NFTs. The capability is then published to a public path, making it accessible to others who wish to interact with the collection.


ProgressNFT Fundamentals

Up Next: NFT with Metadata

50%


Related Recipes

14 Oct 2022
Mint NFT
Beginner
14 Oct 2022
Collection for Holding NFTs
Beginner
14 Oct 2022
NFT with Metadata
Beginner
01 Apr 2022
Metadata Views
Beginner