Smart Contract
LNVCT
A.1e3c78c6d580273b.LNVCT
1// Description: Smart Contract for Live Nation Virtual Commemorative Tickets
2// SPDX-License-Identifier: UNLICENSED
3
4import NonFungibleToken from 0x1d7e57aa55817448
5import MetadataViews from 0x1d7e57aa55817448
6import ViewResolver from 0x1d7e57aa55817448
7
8access(all) contract LNVCT : NonFungibleToken {
9 access(all) var totalSupply: UInt64
10 access(all) var maxEditionNumbersForShows: {String: UInt64}
11 access(all) var name: String
12
13 access(all) event ContractInitialized()
14 access(all) event Withdraw(id: UInt64, from: Address?)
15 access(all) event Deposit(id: UInt64, to: Address?)
16
17 access(all) let CollectionStoragePath: StoragePath
18 access(all) let CollectionPublicPath: PublicPath
19 access(all) let MinterStoragePath: StoragePath
20
21 access(all) struct Rarity {
22 access(all) let rarity: UFix64?
23 access(all) let rarityName: String
24 access(all) let parts: {String: RarityPart}
25
26 init(rarity: UFix64?, rarityName: String, parts: {String: RarityPart}) {
27 self.rarity = rarity
28 self.rarityName = rarityName
29 self.parts = parts
30 }
31 }
32
33 access(all) struct RarityPart {
34 access(all) let rarity: UFix64?
35 access(all) let rarityName: String
36 access(all) let name: String
37
38 init(rarity: UFix64?, rarityName: String, name: String) {
39 self.rarity = rarity
40 self.rarityName = rarityName
41 self.name = name
42 }
43 }
44
45 access(all) resource interface NFTModifier {
46 access(account) fun markAttendanceHelper(attendance: String)
47 access(account) fun setURLMetadataHelper(newURL: String, newThumbnail: String)
48 access(account) fun setRarityHelper(rarity: UFix64, rarityName: String, rarityValue: String)
49 access(account) fun setEditionHelper(editionNumber: UInt64, maxEdition: UInt64)
50 access(account) fun setMaxEditionForShowHelper(description: String, maxEdition: UInt64)
51 access(account) fun setMetadataHelper(metadata_name: String, metadata_value: String)
52 }
53
54 access(all) resource NFT : NonFungibleToken.NFT, NFTModifier {
55 access(all) let id: UInt64
56 access(all) var link: String
57 access(all) var batch: UInt32
58 access(all) var sequence: UInt16
59 access(all) var limit: UInt16
60 access(all) var attendance: String
61 access(all) var name: String
62 access(all) var description: String
63 access(all) var thumbnail: String
64 access(all) var rarity: UFix64?
65 access(all) var rarityName: String
66 access(all) var rarityValue: String
67 access(all) var parts: {String: RarityPart}
68 access(all) var editionNumber: UInt64
69 access(all) var maxEdition: UInt64?
70 access(all) var metadata: {String: String}
71
72 access(account) fun markAttendanceHelper(attendance: String) {
73 self.attendance = attendance
74 log("Attendance is set to: ")
75 log(self.attendance)
76 }
77
78 access(account) fun setURLMetadataHelper(newURL: String, newThumbnail: String) {
79 self.link = newURL
80 self.thumbnail = newThumbnail
81 log("URL metadata is set to: ")
82 log(self.link)
83 log(self.thumbnail)
84 }
85
86 access(account) fun setRarityHelper(rarity: UFix64, rarityName: String, rarityValue: String) {
87 self.rarity = rarity
88 self.rarityName = rarityName
89 self.rarityValue = rarityValue
90 self.parts = {rarityName: RarityPart(rarity: rarity, rarityName: rarityName, name: rarityValue)}
91 log("Rarity metadata is updated")
92 }
93
94 access(account) fun setEditionHelper(editionNumber: UInt64, maxEdition: UInt64) {
95 self.editionNumber = editionNumber
96 self.maxEdition = maxEdition
97 log("Edition metadata is updated")
98 }
99
100 access(account) fun setMaxEditionForShowHelper(description: String, maxEdition: UInt64) {
101 LNVCT.maxEditionNumbersForShows.insert(key: description, maxEdition)
102 log("Max Edition metadata for the Show is updated")
103 }
104
105 access(account) fun setMetadataHelper(metadata_name: String, metadata_value: String) {
106 self.metadata.insert(key: metadata_name, metadata_value)
107 log("Custom Metadata store is updated")
108 }
109
110 init(
111 initID: UInt64,
112 initlink: String,
113 initbatch: UInt32,
114 initsequence: UInt16,
115 initlimit: UInt16,
116 name: String,
117 description: String,
118 thumbnail: String,
119 editionNumber: UInt64,
120 metadata: {String: String}
121 ) {
122 self.id = initID
123 self.link = initlink
124 self.batch = initbatch
125 self.sequence = initsequence
126 self.limit = initlimit
127 self.attendance = "null"
128 self.name = name
129 self.description = description
130 self.thumbnail = thumbnail
131 self.rarity = nil
132 self.rarityName = "Tier"
133 self.rarityValue = "null"
134 self.parts = {self.rarityName: RarityPart(rarity: self.rarity, rarityName: self.rarityName, name: self.rarityValue)}
135 self.editionNumber = editionNumber
136
137 let containsShowName = LNVCT.maxEditionNumbersForShows.containsKey(description)
138 if containsShowName {
139 let currentMaxEditionValue = LNVCT.maxEditionNumbersForShows[description] ?? nil
140 self.maxEdition = currentMaxEditionValue
141 } else {
142 self.maxEdition = nil
143 }
144
145 self.metadata = metadata
146 }
147
148 /// createEmptyCollection creates an empty Collection
149 /// and returns it to the caller so that they can own NFTs
150 /// @{NonFungibleToken.Collection}
151 access(all) fun createEmptyCollection(): @{NonFungibleToken.Collection} {
152 return <-LNVCT.createEmptyCollection(nftType: Type<@LNVCT.NFT>())
153 }
154
155 access(all) view fun getViews(): [Type] {
156 return [
157 Type<MetadataViews.NFTCollectionData>()
158 ]
159 }
160
161 access(all) fun resolveView(_ view: Type): AnyStruct? {
162 switch view {
163 case Type<MetadataViews.NFTCollectionData>():
164 return LNVCT.resolveContractView(resourceType: Type<@LNVCT.NFT>(), viewType: Type<MetadataViews.NFTCollectionData>())
165 }
166 return nil
167 }
168 }
169
170
171 access(all) resource interface LNVCTCollectionPublic {
172 // Depraecated
173 }
174
175 access(all) resource Collection: NonFungibleToken.Collection, LNVCTCollectionPublic {
176 access(all) var ownedNFTs: @{UInt64: {NonFungibleToken.NFT}}
177
178 init() {
179 self.ownedNFTs <- {}
180 }
181
182 /// getSupportedNFTTypes returns a list of NFT types that this receiver accepts
183 access(all) view fun getSupportedNFTTypes(): {Type: Bool} {
184 let supportedTypes: {Type: Bool} = {}
185 supportedTypes[Type<@LNVCT.NFT>()] = true
186 return supportedTypes
187 }
188
189 /// Returns whether or not the given type is accepted by the collection
190 /// A collection that can accept any type should just return true by default
191 access(all) view fun isSupportedNFTType(type: Type): Bool {
192 return type == Type<@LNVCT.NFT>()
193 }
194
195
196 /// withdraw removes an NFT from the collection and moves it to the caller
197 access(NonFungibleToken.Withdraw) fun withdraw(withdrawID: UInt64): @{NonFungibleToken.NFT} {
198 let token <- self.ownedNFTs.remove(key: withdrawID)
199 ?? panic("Could not withdraw an NFT with the provided ID from the collection")
200
201 return <-token
202 }
203
204
205 access(all) fun deposit(token: @{NonFungibleToken.NFT}) {
206 let token <- token as! @LNVCT.NFT
207 let id = token.id
208
209 // add the new token to the dictionary which removes the old one
210 let oldToken <- self.ownedNFTs[token.id] <- token
211
212 destroy oldToken
213
214 }
215
216 /// getIDs returns an array of the IDs that are in the collection
217 access(all) view fun getIDs(): [UInt64] {
218 return self.ownedNFTs.keys
219 }
220
221 /// Gets the amount of NFTs stored in the collection
222 access(all) view fun getLength(): Int {
223 return self.ownedNFTs.length
224 }
225
226
227 access(all) view fun borrowNFT(_ id: UInt64): &{NonFungibleToken.NFT}? {
228 return (&self.ownedNFTs[id] as &{NonFungibleToken.NFT}?)
229 }
230
231 /// Borrow the view resolver for the specified NFT ID
232 access(all) view fun borrowViewResolver(id: UInt64): &{ViewResolver.Resolver}? {
233 if let nft = &self.ownedNFTs[id] as &{NonFungibleToken.NFT}? {
234 return nft as &{ViewResolver.Resolver}
235 }
236 return nil
237 }
238
239 /// createEmptyCollection creates an empty Collection of the same type
240 /// and returns it to the caller
241 /// @return A an empty collection of the same type
242 access(all) fun createEmptyCollection(): @{NonFungibleToken.Collection} {
243 return <- LNVCT.createEmptyCollection(nftType: Type<@LNVCT.NFT>())
244 }
245
246 }
247
248 /// createEmptyCollection creates an empty Collection for the specified NFT type
249 /// and returns it to the caller so that they can own NFTs
250 access(all) fun createEmptyCollection(nftType: Type): @{NonFungibleToken.Collection} {
251 return <- create Collection()
252 }
253
254 /// Function that returns all the Metadata Views implemented by a Non Fungible Token
255 ///
256 /// @return An array of Types defining the implemented views. This value will be used by
257 /// developers to know which parameter to pass to the resolveView() method.
258 ///
259 access(all) view fun getContractViews(resourceType: Type?): [Type] {
260 return [
261 Type<MetadataViews.NFTCollectionData>()]
262 }
263
264 /// Function that resolves a metadata view for this contract.
265 ///
266 /// @param view: The Type of the desired view.
267 /// @return A structure representing the requested view.
268 ///
269 access(all) fun resolveContractView(resourceType: Type?, viewType: Type): AnyStruct? {
270 switch viewType {
271 case Type<MetadataViews.NFTCollectionData>():
272 let collectionData = MetadataViews.NFTCollectionData(
273 storagePath: self.CollectionStoragePath,
274 publicPath: self.CollectionPublicPath,
275 publicCollection: Type<&LNVCT.Collection>(),
276 publicLinkedType: Type<&LNVCT.Collection>(),
277 createEmptyCollectionFunction: (fun(): @{NonFungibleToken.Collection} {
278 return <-LNVCT.createEmptyCollection(nftType: Type<@LNVCT.NFT>())
279 })
280 )
281 return collectionData
282
283 }
284 return nil
285 }
286
287 /// Resource that an admin or something similar would own to be
288 /// able to mint new NFTs
289 ///
290 access(all) resource NFTMinter {
291
292 /// mintNFT mints a new NFT with a new ID
293 /// and returns it to the calling context
294 access(all) fun mintNFT(
295 glink: String,
296 gbatch: UInt32,
297 glimit: UInt16,
298 gsequence: UInt16,
299 name: String,
300 description: String,
301 thumbnail: String,
302 editionNumber: UInt64,
303 metadata: {String: String} // changed from String:String to String:AnyStruct
304 ): @NFT {
305
306 let tokenID = (UInt64(gbatch) << 32) | (UInt64(glimit) << 16) | UInt64(gsequence)
307
308 // let metadata: {String: AnyStruct} = {}
309
310 // this piece of metadata will be used to show embedding rarity into a trait
311 metadata["foo"] = "bar"
312
313 // create a new NFT
314 var newNFT <- create NFT(
315 initID: tokenID,
316 initlink: glink,
317 initbatch: gbatch,
318 initsequence: gsequence,
319 initlimit: glimit,
320 name: name,
321 description: description,
322 thumbnail: thumbnail,
323 editionNumber: editionNumber,
324 metadata: metadata
325 )
326
327 return <-newNFT
328 }
329 }
330
331 access(all) resource Modifier {
332 access(all) var ModifierID: UInt64
333
334 access(all) fun markAttendance(currentNFT: &LNVCT.NFT?, attendance: String): String {
335 let ref2 = currentNFT!
336 ref2.markAttendanceHelper(attendance: attendance)
337 log("Attendance is set to: ")
338 log(ref2.attendance)
339 return ref2.attendance
340 }
341
342 access(all) fun setURLMetadata(currentNFT: &LNVCT.NFT?, newURL: String, newThumbnail: String): String {
343 let ref2 = currentNFT!
344 ref2.setURLMetadataHelper(newURL: newURL, newThumbnail: newThumbnail)
345 log("URL metadata is set to: ")
346 log(newURL)
347 return newURL
348 }
349
350 access(all) fun setRarity(currentNFT: &LNVCT.NFT?, rarity: UFix64, rarityName: String, rarityValue: String) {
351 let ref2 = currentNFT!
352 ref2.setRarityHelper(rarity: rarity, rarityName: rarityName, rarityValue: rarityValue)
353 log("Rarity metadata is updated")
354 }
355
356 access(all) fun setEdition(currentNFT: &LNVCT.NFT?, editionNumber: UInt64, maxEdition: UInt64) {
357 let ref2 = currentNFT!
358 ref2.setEditionHelper(editionNumber: editionNumber, maxEdition: maxEdition)
359 log("Edition metadata is updated")
360 }
361
362 access(all) fun setMaxEditionForShow(description: String, maxEdition: UInt64) {
363 LNVCT.maxEditionNumbersForShows.insert(key: description, maxEdition)
364 log("Max Edition metadata for the Show is updated")
365 }
366
367 access(all) fun setMetadata(currentNFT: &LNVCT.NFT?, metadata_name: String, metadata_value: String) {
368 let ref2 = currentNFT!
369 ref2.setMetadataHelper(metadata_name: metadata_name, metadata_value: metadata_value)
370 log("Custom Metadata store is updated")
371 }
372
373 init() {
374 self.ModifierID = 0
375 }
376 }
377
378 init() {
379 self.CollectionStoragePath = /storage/LNVCTCollection
380 self.CollectionPublicPath = /public/LNVCTCollection
381 self.MinterStoragePath = /storage/LNVCTMinter
382 self.totalSupply = 0
383 self.maxEditionNumbersForShows = {}
384 self.name = "Live Nation Virtual Commemorative Tickets"
385
386 let collection <- create Collection()
387 self.account.storage.save(<-collection, to: self.CollectionStoragePath)
388
389 let collectionCap = self.account.capabilities.storage.issue<&LNVCT.Collection>(self.CollectionStoragePath)
390 self.account.capabilities.publish(collectionCap, at: self.CollectionPublicPath)
391
392 let minter <- create NFTMinter()
393 self.account.storage.save(<-minter, to: self.MinterStoragePath)
394
395 let modifier <- create Modifier()
396 self.account.storage.save(<-modifier, to: /storage/LNVCTModifier)
397
398 emit ContractInitialized()
399 }
400}