Smart Contract
TouchstonePartyFlavorz
A.c4b1f4387748f389.TouchstonePartyFlavorz
1import NonFungibleToken from 0x1d7e57aa55817448
2import MetadataViews from 0x1d7e57aa55817448
3import FungibleToken from 0xf233dcee88fe0abe
4import FlowToken from 0x1654653399040a61
5import ViewResolver from 0x1d7e57aa55817448
6
7// CREATED BY: Touchstone (https://touchstone.city/), a platform crafted by your best friends at Emerald City DAO (https://ecdao.org/).
8// STATEMENT: This contract promises to keep the 5% royalty off of primary sales and 2.5% off of secondary sales to Emerald City DAO or risk permanent suspension from participation in the DAO and its tools.
9
10// import "NonFungibleToken"
11// import "MetadataViews"
12// import "FungibleToken"
13// import "FlowToken"
14// import "ViewResolver"
15
16// import "MintVerifiers"
17// import "FUSD"
18// import "EmeraldPass"
19
20access(all) contract TouchstonePartyFlavorz: NonFungibleToken {
21
22 // Collection Information
23 access(self) let collectionInfo: {String: AnyStruct}
24
25 // Contract Information
26 access(all) var nextEditionId: UInt64
27 access(all) var nextMetadataId: UInt64
28 access(all) var totalSupply: UInt64
29
30 // Events
31 access(all) event ContractInitialized()
32 access(all) event Withdraw(id: UInt64, from: Address?)
33 access(all) event Deposit(id: UInt64, to: Address?)
34 access(all) event TouchstonePurchase(id: UInt64, recipient: Address, metadataId: UInt64, name: String, description: String, image: MetadataViews.IPFSFile, price: UFix64)
35 access(all) event Minted(id: UInt64, recipient: Address, metadataId: UInt64)
36 access(all) event MintBatch(metadataIds: [UInt64], recipients: [Address])
37
38 // Paths
39 access(all) let CollectionStoragePath: StoragePath
40 access(all) let CollectionPublicPath: PublicPath
41 access(all) let CollectionPrivatePath: PrivatePath
42 access(all) let AdministratorStoragePath: StoragePath
43
44 // Maps metadataId of NFT to NFTMetadata
45 access(account) let metadatas: {UInt64: NFTMetadata}
46
47 // Maps the metadataId of an NFT to the primary buyer
48 access(account) let primaryBuyers: {Address: {UInt64: [UInt64]}}
49
50 access(account) let nftStorage: @{Address: {UInt64: NFT}}
51
52 access(all) struct NFTMetadata {
53 access(all) let metadataId: UInt64
54 access(all) let name: String
55 access(all) let description: String
56 // The main image of the NFT
57 access(all) let image: MetadataViews.IPFSFile
58 // An optional thumbnail that can go along with it
59 // for easier loading
60 access(all) let thumbnail: MetadataViews.IPFSFile?
61 // If price is nil, defaults to the collection price
62 access(all) let price: UFix64?
63 access(all) var extra: {String: AnyStruct}
64 access(all) let supply: UInt64
65 access(all) let purchasers: {UInt64: Address}
66
67 access(account) fun purchased(serial: UInt64, buyer: Address) {
68 self.purchasers[serial] = buyer
69 }
70
71 init(_name: String, _description: String, _image: MetadataViews.IPFSFile, _thumbnail: MetadataViews.IPFSFile?, _price: UFix64?, _extra: {String: AnyStruct}, _supply: UInt64) {
72 self.metadataId = TouchstonePartyFlavorz.nextMetadataId
73 self.name = _name
74 self.description = _description
75 self.image = _image
76 self.thumbnail = _thumbnail
77 self.price = _price
78 self.extra = _extra
79 self.supply = _supply
80 self.purchasers = {}
81 }
82 }
83
84 access(all) resource NFT: NonFungibleToken.NFT, ViewResolver.Resolver {
85 // The 'id' is the same as the 'uuid'
86 access(all) let id: UInt64
87 // The 'metadataId' is what maps this NFT to its 'NFTMetadata'
88 access(all) let metadataId: UInt64
89 access(all) let serial: UInt64
90
91 access(all) view fun getMetadata(): NFTMetadata {
92 return TouchstonePartyFlavorz.getNFTMetadata(self.metadataId)!
93 }
94
95 access(all) view fun getViews(): [Type] {
96 return [
97 Type<MetadataViews.Display>(),
98 Type<MetadataViews.ExternalURL>(),
99 Type<MetadataViews.NFTCollectionData>(),
100 Type<MetadataViews.NFTCollectionDisplay>(),
101 Type<MetadataViews.Royalties>(),
102 Type<MetadataViews.Serial>(),
103 Type<MetadataViews.Traits>(),
104 Type<MetadataViews.NFTView>()
105 ]
106 }
107
108 access(all) fun resolveView(_ view: Type): AnyStruct? {
109 switch view {
110 case Type<MetadataViews.Display>():
111 let metadata = self.getMetadata()
112 return MetadataViews.Display(
113 name: metadata.name,
114 description: metadata.description,
115 thumbnail: metadata.thumbnail ?? metadata.image
116 )
117 case Type<MetadataViews.NFTCollectionData>():
118 return MetadataViews.NFTCollectionData(
119 storagePath: TouchstonePartyFlavorz.CollectionStoragePath,
120 publicPath: TouchstonePartyFlavorz.CollectionPublicPath,
121 publicCollection: Type<&Collection>(),
122 publicLinkedType: Type<&Collection>(),
123 createEmptyCollectionFunction: (fun (): @{NonFungibleToken.Collection} {
124 return <- TouchstonePartyFlavorz.createEmptyCollection(nftType: Type<@TouchstonePartyFlavorz.Collection>())
125 })
126 )
127 case Type<MetadataViews.ExternalURL>():
128 return MetadataViews.ExternalURL("https://touchstone.city/discover/".concat(self.owner!.address.toString()).concat("/TouchstonePartyFlavorz"))
129 case Type<MetadataViews.NFTCollectionDisplay>():
130 let squareMedia = MetadataViews.Media(
131 file: TouchstonePartyFlavorz.getCollectionAttribute(key: "image") as! MetadataViews.IPFSFile,
132 mediaType: "image"
133 )
134
135 // If a banner image exists, use it
136 // Otherwise, default to the main square image
137 var bannerMedia: MetadataViews.Media? = nil
138 if let bannerImage = TouchstonePartyFlavorz.getOptionalCollectionAttribute(key: "bannerImage") as! MetadataViews.IPFSFile? {
139 bannerMedia = MetadataViews.Media(
140 file: bannerImage,
141 mediaType: "image"
142 )
143 }
144 return MetadataViews.NFTCollectionDisplay(
145 name: TouchstonePartyFlavorz.getCollectionAttribute(key: "name") as! String,
146 description: TouchstonePartyFlavorz.getCollectionAttribute(key: "description") as! String,
147 externalURL: MetadataViews.ExternalURL("https://touchstone.city/discover/".concat(self.owner!.address.toString()).concat("/TouchstonePartyFlavorz")),
148 squareImage: squareMedia,
149 bannerImage: bannerMedia ?? squareMedia,
150 socials: TouchstonePartyFlavorz.getCollectionAttribute(key: "socials") as! {String: MetadataViews.ExternalURL}
151 )
152 case Type<MetadataViews.Royalties>():
153 return MetadataViews.Royalties([
154 // This is for Emerald City in favor of producing Touchstone, a free platform for our users. Failure to keep this in the contract may result in permanent suspension from Emerald City.
155 MetadataViews.Royalty(
156 receiver: getAccount(0x5643fd47a29770e7).capabilities.get<&FlowToken.Vault>(/public/flowTokenReceiver),
157 cut: 0.025, // 2.5% royalty on secondary sales
158 description: "Emerald City DAO receives a 2.5% royalty from secondary sales because this collection was created using Touchstone (https://touchstone.city/), a tool for creating your own NFT collections, crafted by Emerald City DAO."
159 )
160 ])
161 case Type<MetadataViews.Serial>():
162 return MetadataViews.Serial(
163 self.serial
164 )
165 case Type<MetadataViews.Traits>():
166 return MetadataViews.dictToTraits(dict: self.getMetadata().extra, excludedNames: nil)
167 case Type<MetadataViews.NFTView>():
168 return MetadataViews.NFTView(
169 id: self.id,
170 uuid: self.uuid,
171 display: self.resolveView(Type<MetadataViews.Display>()) as! MetadataViews.Display?,
172 externalURL: self.resolveView(Type<MetadataViews.ExternalURL>()) as! MetadataViews.ExternalURL?,
173 collectionData: self.resolveView(Type<MetadataViews.NFTCollectionData>()) as! MetadataViews.NFTCollectionData?,
174 collectionDisplay: self.resolveView(Type<MetadataViews.NFTCollectionDisplay>()) as! MetadataViews.NFTCollectionDisplay?,
175 royalties: self.resolveView(Type<MetadataViews.Royalties>()) as! MetadataViews.Royalties?,
176 traits: self.resolveView(Type<MetadataViews.Traits>()) as! MetadataViews.Traits?
177 )
178 }
179 return nil
180 }
181
182 access(all) fun createEmptyCollection(): @{NonFungibleToken.Collection} {
183 return <- TouchstonePartyFlavorz.createEmptyCollection(nftType: Type<@TouchstonePartyFlavorz.Collection>())
184 }
185
186 init(_metadataId: UInt64, _serial: UInt64, _recipient: Address) {
187 pre {
188 TouchstonePartyFlavorz.metadatas[_metadataId] != nil:
189 "This NFT does not exist yet."
190 _serial < TouchstonePartyFlavorz.getNFTMetadata(_metadataId)!.supply:
191 "This serial does not exist for this metadataId."
192 !TouchstonePartyFlavorz.getNFTMetadata(_metadataId)!.purchasers.containsKey(_serial):
193 "This serial has already been purchased."
194 }
195 self.id = self.uuid
196 self.metadataId = _metadataId
197 self.serial = _serial
198
199 // Update the buyers list so we keep track of who is purchasing
200 // if let buyersRef: auth(Mutate) &{UInt64: [UInt64]} = &TouchstonePartyFlavorz.primaryBuyers[_recipient] {
201 // if let metadataIdMap: &[UInt64] = buyersRef[_metadataId] {
202 // metadataIdMap.append(_serial)
203 // } else {
204 // buyersRef[_metadataId] = [_serial]
205 // }
206 // } else {
207 // TouchstonePartyFlavorz.primaryBuyers[_recipient] = {_metadataId: [_serial]}
208 // }
209
210 // Update who bought this serial inside NFTMetadata so it cannot be purchased again.
211 let metadataRef = (&TouchstonePartyFlavorz.metadatas[_metadataId] as &NFTMetadata?)!
212 metadataRef.purchased(serial: _serial, buyer: _recipient)
213
214 TouchstonePartyFlavorz.totalSupply = TouchstonePartyFlavorz.totalSupply + 1
215 emit Minted(id: self.id, recipient: _recipient, metadataId: _metadataId)
216 }
217 }
218
219 access(all) resource Collection: NonFungibleToken.Collection, NonFungibleToken.Provider, NonFungibleToken.Receiver, NonFungibleToken.CollectionPublic, ViewResolver.ResolverCollection {
220 // dictionary of NFT conforming tokens
221 // NFT is a resource type with an 'UInt64' ID field
222 access(all) var ownedNFTs: @{UInt64: {NonFungibleToken.NFT}}
223
224 // withdraw removes an NFT from the collection and moves it to the caller
225 access(NonFungibleToken.Withdraw) fun withdraw(withdrawID: UInt64): @{NonFungibleToken.NFT} {
226 let token <- self.ownedNFTs.remove(key: withdrawID) ?? panic("missing NFT")
227
228 emit Withdraw(id: token.id, from: self.owner?.address)
229
230 return <-token
231 }
232
233 // deposit takes a NFT and adds it to the collections dictionary
234 // and adds the ID to the id array
235 access(all) fun deposit(token: @{NonFungibleToken.NFT}) {
236 let token: @TouchstonePartyFlavorz.NFT <- token as! @TouchstonePartyFlavorz.NFT
237
238 let id: UInt64 = token.id
239
240 // add the new token to the dictionary which removes the old one
241 let oldToken: @{NonFungibleToken.NFT}? <- self.ownedNFTs[id] <- token
242
243 emit Deposit(id: id, to: self.owner?.address)
244
245 destroy oldToken
246 }
247
248 // getIDs returns an array of the IDs that are in the collection
249 access(all) view fun getIDs(): [UInt64] {
250 return self.ownedNFTs.keys
251 }
252
253 access(all) view fun getLength(): Int {
254 return self.ownedNFTs.length
255 }
256
257 access(all) fun forEachID(_ f: fun (UInt64): Bool): Void {}
258
259 /// getSupportedNFTTypes returns a list of NFT types that this receiver accepts
260 access(all) view fun getSupportedNFTTypes(): {Type: Bool} {
261 let supportedTypes: {Type: Bool} = {}
262 supportedTypes[Type<@TouchstonePartyFlavorz.NFT>()] = true
263 return supportedTypes
264 }
265
266 /// Returns whether or not the given type is accepted by the collection
267 /// A collection that can accept any type should just return true by default
268 access(all) view fun isSupportedNFTType(type: Type): Bool {
269 return type == Type<@TouchstonePartyFlavorz.NFT>()
270 }
271
272 // borrowNFT gets a reference to an NFT in the collection
273 // so that the caller can read its metadata and call its methods
274 access(all) view fun borrowNFT(_ id: UInt64): &{NonFungibleToken.NFT}? {
275 return (&self.ownedNFTs[id])
276 }
277
278 access(all) view fun borrowViewResolver(id: UInt64): &{ViewResolver.Resolver}? {
279 pre {
280 self.ownedNFTs[id] != nil : "NFT not in collection"
281 }
282 let nft: &{NonFungibleToken.NFT} = (&self.ownedNFTs[id])!
283 let tokenRef = nft as! &TouchstonePartyFlavorz.NFT
284 return tokenRef
285 }
286
287 access(all) fun claim() {
288 if let storage: auth(Mutate) &{UInt64: TouchstonePartyFlavorz.NFT} = &TouchstonePartyFlavorz.nftStorage[self.owner!.address] {
289 for id in storage.keys {
290 self.deposit(token: <- storage.remove(key: id)!)
291 }
292 }
293 }
294
295 access(all) fun createEmptyCollection(): @{NonFungibleToken.Collection} {
296 return <- TouchstonePartyFlavorz.createEmptyCollection(nftType: Type<@TouchstonePartyFlavorz.NFT>())
297 }
298
299 init () {
300 self.ownedNFTs <- {}
301 }
302
303 }
304
305 // A function to mint NFTs.
306 // You can only call this function if minting
307 // is currently active.
308 access(all) fun mintNFT(metadataId: UInt64, recipient: &{NonFungibleToken.Receiver}, payment: @FlowToken.Vault, serial: UInt64): UInt64 {
309 pre {
310 self.canMint(): "Minting is currently closed by the Administrator!"
311 payment.balance == self.getPriceOfNFT(metadataId):
312 "Payment does not match the price. You passed in ".concat(payment.balance.toString()).concat(" but this NFT costs ").concat(self.getPriceOfNFT(metadataId)!.toString())
313 }
314 let price: UFix64 = self.getPriceOfNFT(metadataId)!
315
316 // Confirm recipient passes all verifiers
317 // for verifier in self.getMintVerifiers() {
318 // let params = {"minter": recipient.owner!.address}
319 // if let error = verifier.verify(params) {
320 // panic(error)
321 // }
322 // }
323
324 // Handle Emerald City DAO royalty (5%)
325 let EmeraldCityTreasury = getAccount(0x5643fd47a29770e7).capabilities.get<&FlowToken.Vault>(/public/flowTokenReceiver)
326 .borrow()!
327 let emeraldCityCut: UFix64 = 0.05 * price
328
329 // Handle royalty to user that was configured upon creation
330 if let royalty = TouchstonePartyFlavorz.getOptionalCollectionAttribute(key: "royalty") as! MetadataViews.Royalty? {
331 royalty.receiver.borrow()!.deposit(from: <- payment.withdraw(amount: price * royalty.cut))
332 }
333
334 EmeraldCityTreasury.deposit(from: <- payment.withdraw(amount: emeraldCityCut))
335
336 // Give the rest to the collection owner
337 let paymentRecipient = self.account.capabilities.get<&FlowToken.Vault>(/public/flowTokenReceiver)
338 .borrow()!
339 paymentRecipient.deposit(from: <- payment)
340
341 // Mint the nft
342 let nft <- create NFT(_metadataId: metadataId, _serial: serial, _recipient: recipient.owner!.address)
343 let nftId: UInt64 = nft.id
344 let metadata = self.getNFTMetadata(metadataId)!
345 self.collectionInfo["profit"] = (self.getCollectionAttribute(key: "profit") as! UFix64) + price
346
347 // Emit event
348 emit TouchstonePurchase(id: nftId, recipient: recipient.owner!.address, metadataId: metadataId, name: metadata.name, description: metadata.description, image: metadata.image, price: price)
349
350 // Deposit nft
351 recipient.deposit(token: <- nft)
352
353 return nftId
354 }
355
356 access(all) resource Administrator {
357 access(all) fun createNFTMetadata(name: String, description: String, imagePath: String, thumbnailPath: String?, ipfsCID: String, price: UFix64?, extra: {String: AnyStruct}, supply: UInt64) {
358 TouchstonePartyFlavorz.metadatas[TouchstonePartyFlavorz.nextMetadataId] = NFTMetadata(
359 _name: name,
360 _description: description,
361 _image: MetadataViews.IPFSFile(
362 cid: ipfsCID,
363 path: imagePath
364 ),
365 _thumbnail: thumbnailPath == nil ? nil : MetadataViews.IPFSFile(cid: ipfsCID, path: thumbnailPath),
366 _price: price,
367 _extra: extra,
368 _supply: supply
369 )
370 TouchstonePartyFlavorz.nextMetadataId = TouchstonePartyFlavorz.nextMetadataId + 1
371 }
372
373 // mintNFT mints a new NFT and deposits
374 // it in the recipients collection
375 access(all) fun mintNFT(metadataId: UInt64, serial: UInt64, recipient: Address) {
376 pre {
377 // EmeraldPass.isActive(user: TouchstonePartyFlavorz.account.address): "You must have an active Emerald Pass subscription to airdrop NFTs. You can purchase Emerald Pass at https://pass.ecdao.org/"
378 }
379 let nft <- create NFT(_metadataId: metadataId, _serial: serial, _recipient: recipient)
380 if let recipientCollection = getAccount(recipient).capabilities.get<&TouchstonePartyFlavorz.Collection>(TouchstonePartyFlavorz.CollectionPublicPath).borrow() {
381 recipientCollection.deposit(token: <- nft)
382 } else {
383 if let storage: auth(Mutate) &{UInt64: TouchstonePartyFlavorz.NFT} = &TouchstonePartyFlavorz.nftStorage[recipient] {
384 storage[nft.id] <-! nft
385 } else {
386 TouchstonePartyFlavorz.nftStorage[recipient] <-! {nft.id: <- nft}
387 }
388 }
389 }
390
391 access(all) fun mintBatch(metadataIds: [UInt64], serials: [UInt64], recipients: [Address]) {
392 pre {
393 metadataIds.length == recipients.length: "You need to pass in an equal number of metadataIds and recipients."
394 }
395 var i = 0
396 while i < metadataIds.length {
397 self.mintNFT(metadataId: metadataIds[i], serial: serials[i], recipient: recipients[i])
398 i = i + 1
399 }
400
401 emit MintBatch(metadataIds: metadataIds, recipients: recipients)
402 }
403
404 // create a new Administrator resource
405 access(all) fun createAdmin(): @Administrator {
406 return <- create Administrator()
407 }
408
409 // change piece of collection info
410 access(all) fun changeField(key: String, value: AnyStruct) {
411 TouchstonePartyFlavorz.collectionInfo[key] = value
412 }
413 }
414
415 // public function that anyone can call to create a new empty collection
416 access(all) fun createEmptyCollection(nftType: Type): @{NonFungibleToken.Collection} {
417 return <- create Collection()
418 }
419
420 // Get information about a NFTMetadata
421 access(all) view fun getNFTMetadata(_ metadataId: UInt64): NFTMetadata? {
422 return self.metadatas[metadataId]
423 }
424
425 access(all) view fun getNFTMetadatas(): {UInt64: NFTMetadata} {
426 return self.metadatas
427 }
428
429 access(all) view fun getPrimaryBuyers(): {Address: {UInt64: [UInt64]}} {
430 return self.primaryBuyers
431 }
432
433 access(all) view fun getCollectionInfo(): {String: AnyStruct} {
434 let collectionInfo = self.collectionInfo
435 collectionInfo["metadatas"] = self.metadatas
436 collectionInfo["primaryBuyers"] = self.primaryBuyers
437 collectionInfo["totalSupply"] = self.totalSupply
438 collectionInfo["nextMetadataId"] = self.nextMetadataId
439 collectionInfo["version"] = 1
440 return collectionInfo
441 }
442
443 access(all) view fun getCollectionAttribute(key: String): AnyStruct {
444 return self.collectionInfo[key] ?? panic(key.concat(" is not an attribute in this collection."))
445 }
446
447 access(all) view fun getOptionalCollectionAttribute(key: String): AnyStruct? {
448 return self.collectionInfo[key]
449 }
450
451 // access(all) fun getMintVerifiers(): [{MintVerifiers.IVerifier}] {
452 // return self.getCollectionAttribute(key: "mintVerifiers") as! [{MintVerifiers.IVerifier}]
453 // }
454
455 access(all) view fun canMint(): Bool {
456 return self.getCollectionAttribute(key: "minting") as! Bool
457 }
458
459 // Returns nil if an NFT with this metadataId doesn't exist
460 access(all) view fun getPriceOfNFT(_ metadataId: UInt64): UFix64? {
461 if let metadata: TouchstonePartyFlavorz.NFTMetadata = self.getNFTMetadata(metadataId) {
462 let defaultPrice: UFix64 = self.getCollectionAttribute(key: "price") as! UFix64
463 if self.getCollectionAttribute(key: "lotteryBuying") as! Bool {
464 return defaultPrice
465 }
466 return metadata.price ?? defaultPrice
467 }
468 // If the metadataId doesn't exist
469 return nil
470 }
471
472 // Returns an mapping of id to NFTMetadata
473 // for the NFTs a user can claim
474 access(all) view fun getClaimableNFTs(user: Address): {UInt64: NFTMetadata} {
475 let answer: {UInt64: NFTMetadata} = {}
476 if let storage = &TouchstonePartyFlavorz.nftStorage[user] as &{UInt64: NFT}? {
477 for id in storage.keys {
478 let nftRef = (storage[id])!
479 answer[id] = self.getNFTMetadata(nftRef.metadataId)
480 }
481 }
482 return answer
483 }
484
485 access(all) view fun getContractViews(resourceType: Type?): [Type] {
486 return [
487 Type<MetadataViews.NFTCollectionData>()
488 ]
489 }
490
491 access(all) fun resolveContractView(resourceType: Type?, viewType: Type): AnyStruct? {
492 return nil
493 }
494
495 init(
496 _name: String,
497 _description: String,
498 _imagePath: String,
499 _bannerImagePath: String?,
500 _minting: Bool,
501 _royalty: MetadataViews.Royalty?,
502 _defaultPrice: UFix64,
503 _paymentType: String,
504 _ipfsCID: String,
505 _lotteryBuying: Bool,
506 _socials: {String: MetadataViews.ExternalURL}
507 // _mintVerifiers: [{MintVerifiers.IVerifier}]
508 ) {
509 // Collection Info
510 self.collectionInfo = {}
511 self.collectionInfo["name"] = _name
512 self.collectionInfo["description"] = _description
513 self.collectionInfo["image"] = MetadataViews.IPFSFile(
514 cid: _ipfsCID,
515 path: _imagePath
516 )
517 if let bannerImagePath = _bannerImagePath {
518 self.collectionInfo["bannerImage"] = MetadataViews.IPFSFile(
519 cid: _ipfsCID,
520 path: _bannerImagePath
521 )
522 }
523 self.collectionInfo["ipfsCID"] = _ipfsCID
524 self.collectionInfo["socials"] = _socials
525 self.collectionInfo["minting"] = _minting
526 self.collectionInfo["lotteryBuying"] = _lotteryBuying
527 if let royalty = _royalty {
528 assert(royalty.receiver.check(), message: "The passed in royalty receiver is not valid. The royalty account must set up the intended payment token.")
529 assert(royalty.cut <= 0.95, message: "The royalty cut cannot be bigger than 95% because 5% goes to Emerald City treasury for primary sales.")
530 self.collectionInfo["royalty"] = royalty
531 }
532 self.collectionInfo["price"] = _defaultPrice
533 self.collectionInfo["paymentType"] = _paymentType
534 self.collectionInfo["dateCreated"] = getCurrentBlock().timestamp
535 // self.collectionInfo["mintVerifiers"] = _mintVerifiers
536 self.collectionInfo["profit"] = 0.0
537
538 self.nextEditionId = 0
539 self.nextMetadataId = 0
540 self.totalSupply = 0
541 self.metadatas = {}
542 self.primaryBuyers = {}
543 self.nftStorage <- {}
544
545 // Set the named paths
546 // We include the user's address in the paths.
547 // This is to prevent clashing with existing
548 // Collection paths in the ecosystem.
549 self.CollectionStoragePath = /storage/TouchstonePartyFlavorzCollection_0xc4b1f4387748f389
550 self.CollectionPublicPath = /public/TouchstonePartyFlavorzCollection_0xc4b1f4387748f389
551 self.CollectionPrivatePath = /private/TouchstonePartyFlavorzCollection_0xc4b1f4387748f389
552 self.AdministratorStoragePath = /storage/TouchstonePartyFlavorzAdministrator_0xc4b1f4387748f389
553
554 // Create a Collection resource and save it to storage
555 let collection <- create Collection()
556 self.account.storage.save(<- collection, to: self.CollectionStoragePath)
557
558 // create a public capability for the collection
559 let pubCap = self.account.capabilities.storage.issue<&Collection>(self.CollectionStoragePath)
560 self.account.capabilities.publish(pubCap, at: self.CollectionPublicPath)
561
562 // Create a Administrator resource and save it to storage
563 let administrator <- create Administrator()
564 self.account.storage.save(<- administrator, to: self.AdministratorStoragePath)
565
566 emit ContractInitialized()
567 }
568}
569