Smart Contract

LNVCT

A.1e3c78c6d580273b.LNVCT

Deployed

6d ago
Feb 20, 2026, 04:15:14 AM UTC

Dependents

13 imports
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}