Creating Collection For Account
Creating Collection For Account
14 Oct 2022
Contributed by Flow Blockchain
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.
Up Next: NFT with Metadata
50%