Creating a Set in Series
Creating a Set in Series
01 Apr 2022
Contributed by Flow Blockchain
Once you've implemented a series for your NFT, you now create Sets so that each NFT is part of a set in a series.
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
// Variable size dictionary of SetData structs
access(self) var setData: {UInt32: NFTSetData}
pub struct NFTSetData {
// Unique ID for the Set
pub let setId: UInt32
// Series ID the Set belongs to
pub let seriesId: UInt32
// Maximum number of editions that can be minted in this Set
pub let maxEditions: UInt32
// The JSON metadata for each NFT edition can be stored off-chain on IPFS.
// This is an optional dictionary of IPFS hashes, which will allow marketplaces
// to pull the metadata for each NFT edition
access(self) var ipfsMetadataHashes: {UInt32: String}
// Set level metadata
// Dictionary of metadata key value pairs
access(self) var metadata: {String: String}
init(
setId: UInt32,
seriesId: UInt32,
maxEditions: UInt32,
ipfsMetadataHashes: {UInt32: String},
metadata: {String: String}) {
self.setId = setId
self.seriesId = seriesId
self.maxEditions = maxEditions
self.metadata = metadata
self.ipfsMetadataHashes = ipfsMetadataHashes
emit SetCreated(seriesId: self.seriesId, setId: self.setId)
}
pub fun getIpfsMetadataHash(editionNum: UInt32): String? {
return self.ipfsMetadataHashes[editionNum]
}
pub fun getMetadata(): {String: String} {
return self.metadata
}
pub fun getMetadataField(field: String): String? {
return self.metadata[field]
}
}
....
// Resource that allows an admin to mint new NFTs
//
pub resource Series {
// Unique ID for the Series
pub let seriesId: UInt32
// Array of NFTSets that belong to this Series
access(self) var setIds: [UInt32]
// Series sealed state
pub var seriesSealedState: Bool;
// Set sealed state
access(self) var setSealedState: {UInt32: Bool};
// Current number of editions minted per Set
access(self) var numberEditionsMintedPerSet: {UInt32: UInt32}
init(
seriesId: UInt32,
metadata: {String: String}) {
self.seriesId = seriesId
self.seriesSealedState = false
self.numberEditionsMintedPerSet = {}
self.setIds = []
self.setSealedState = {}
SetAndSeries.seriesData[seriesId] = SeriesData(
seriesId: seriesId,
metadata: metadata
)
}
pub fun addNftSet(
setId: UInt32,
maxEditions: UInt32,
ipfsMetadataHashes: {UInt32: String},
metadata: {String: String}) {
pre {
self.setIds.contains(setId) == false: "The Set has already been added to the Series."
}
// Create the new Set struct
var newNFTSet = NFTSetData(
setId: setId,
seriesId: self.seriesId,
maxEditions: maxEditions,
ipfsMetadataHashes: ipfsMetadataHashes,
metadata: metadata
)
// Add the NFTSet to the array of Sets
self.setIds.append(setId)
// Initialize the NFT edition count to zero
self.numberEditionsMintedPerSet[setId] = 0
// Store it in the sets mapping field
SetAndSeries.setData[setId] = newNFTSet
emit SetCreated(seriesId: self.seriesId, setId: setId)
}
....
//rest of code below
}
Similarly to how you had created and assigned variables for a Series and SeriesData, you do the same for setData so that each set is managed correctly and you don't create the same set.
Afterwards you would create a struct for the NFT Set Data that would lay out all the variables you need for a set and what you need to do to initialize it.
Then you would have your series resource that would only exist in your account if you had used the admin account to create a new series. Once that series is created you have the availability to access the addNftSet function to create a new set.
Here you would enter in all the necessary parameters that go into creating an NFT Set. Once that's taken in you first check to make sure that the series doesn't already contain that setId.
If that is true then you establish the new NFTSetData struct. Afterwards you add the setId to the setId's array. Then you initialize the number of NFTS minted to 0 based on your setID # in the series because you are creating a brand new set.
Afterwards you store the setId and the NFTSetData struct in the setData dictionary where all the sets are able to be tracked.
Transaction Example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import SetAndSeries from 0x01
transaction {
let adminCheck: &SetAndSeries.Admin
let seriesRef: &SetAndSeries.Series
prepare(acct: AuthAccount) {
self.adminCheck = acct.borrow<&SetAndSeries.Admin>(from: SetAndSeries.AdminStoragePath)
?? panic("could not borrow admin reference")
self.seriesRef = self.adminCheck.borrowSeries(seriesId: 1)
}
execute {
self.seriesRef.addNftSet(setId: 1, maxEditions: 5, ipfsMetadataHashes: {}, metadata: {"Rookie": "2004"})
log("set added")
}
}
Here you execute a transaction to create a new set. First you borrow a reference to the admin resource from the AuthAccount and afterwards you use the admin account to access the borrowSeries function.
Once that happens you are able to get access to the series you input in the parameters if it exists. After that you have access the addNftSet function to add as many sets as you would like.
Up Next: Minting NFTs in a Set
62%