Smart Contract

SGKCLDR_cb_dinosaur2024

A.413f55f23848582c.SGKCLDR_cb_dinosaur2024

Deployed

3d ago
Feb 25, 2026, 07:54:26 AM UTC

Dependents

2 imports
1//  SPDX-License-Identifier: UNLICENSED
2//
3//
4import NonFungibleToken from 0x1d7e57aa55817448
5import Anique from 0xe2e1689b53e92a82
6
7pub contract SGKCLDR_cb_dinosaur2024: NonFungibleToken, Anique {
8    // -----------------------------------------------------------------------
9    // SGKCLDR_cb_dinosaur2024 contract Events
10    // -----------------------------------------------------------------------
11
12    // Events for Contract-Related actions
13    //
14    // Emitted when the SGKCLDR_cb_dinosaur2024 contract is created
15    pub event ContractInitialized()
16
17    // Events for Item-Related actions
18    //
19    // Emitted when a new Item struct is created
20    pub event ItemCreated(id: UInt32, metadata: {String:String})
21
22    // Events for Collectible-Related actions
23    //
24    // Emitted when an CollectibleData NFT is minted
25    pub event CollectibleMinted(collectibleID: UInt64, itemID: UInt32, serialNumber: UInt32)
26    // Emitted when an CollectibleData NFT is destroyed
27    pub event CollectibleDestroyed(collectibleID: UInt64)
28
29    // events for Collection-related actions
30    //
31    // Emitted when an CollectibleData is withdrawn from a Collection
32    pub event Withdraw(id: UInt64, from: Address?)
33    // Emitted when an CollectibleData is deposited into a Collection
34    pub event Deposit(id: UInt64, to: Address?)
35
36    // paths
37    pub let collectionStoragePath: StoragePath
38    pub let collectionPublicPath: PublicPath
39    pub let collectionPrivatePath: PrivatePath
40    pub let adminStoragePath: StoragePath
41    pub let saleCollectionStoragePath: StoragePath
42    pub let saleCollectionPublicPath: PublicPath
43
44    // -----------------------------------------------------------------------
45    // SGKCLDR_cb_dinosaur2024 contract-level fields.
46    // These contain actual values that are stored in the smart contract.
47    // -----------------------------------------------------------------------
48
49    // fields for Item-related
50    //
51    // variable size dictionary of Item resources
52    access(self) var items: @{UInt32: Item}
53
54    // The ID that is used to create Items.
55    pub var nextItemID: UInt32
56
57    // fields for Collectible-related
58    //
59    // Total number of CollectibleData NFTs that have been minted ever.
60    pub var totalSupply: UInt64
61
62    // -----------------------------------------------------------------------
63    // SGKCLDR_cb_dinosaur2024 contract-level Composite Type definitions
64    // -----------------------------------------------------------------------
65
66    // The structure that represents Item
67    // each digital content which SGKCLDR_cb_dinosaur2024 deal with on Flow
68    //
69    pub struct ItemData {
70
71        pub let itemID: UInt32
72
73        pub let metadata: {String: String}
74
75        init(itemID: UInt32) {
76            let item = (&SGKCLDR_cb_dinosaur2024.items[itemID] as &Item?)!
77
78            self.itemID = item.itemID
79            self.metadata = item.metadata
80        }
81   }
82
83    // Item is a resource type that contains the functions to mint Collectibles.
84    //
85    // It is stored in a private field in the contract so that
86    // the admin resource can call its methods and that there can be
87    // public getters for some of its fields
88    //
89    // The admin can mint Collectibles that refer from Item.
90    pub resource Item {
91
92        // unique ID for the Item
93        pub let itemID: UInt32
94
95        // Stores all the metadata about the item as a string mapping
96        // This is not the long term way NFT metadata will be stored. It's a temporary
97        // construct while we figure out a better way to do metadata.
98        //
99        pub let metadata: {String: String}
100
101        // The number of Collectibles that have been minted per Item.
102        access(contract) var numberMintedPerItem: UInt32
103
104        init(metadata: {String: String}) {
105            pre {
106                metadata.length != 0: "New Item metadata cannot be empty"
107            }
108            self.itemID = SGKCLDR_cb_dinosaur2024.nextItemID
109            self.metadata = metadata
110            self.numberMintedPerItem = 0
111
112            // increment the nextItemID so that it isn't used again
113            SGKCLDR_cb_dinosaur2024.nextItemID = SGKCLDR_cb_dinosaur2024.nextItemID + 1
114
115            emit ItemCreated(id: self.itemID, metadata: metadata)
116        }
117
118        // mintCollectible mints a new Collectible and returns the newly minted Collectible
119        //
120        // Returns: The NFT that was minted
121        //
122        pub fun mintCollectible(): @NFT {
123            // get the number of Collectibles that have been minted for this Item
124            // to use as this Collectible's serial number
125            let numInItem = self.numberMintedPerItem
126
127            // mint the new Collectible
128            let newCollectible: @NFT <- create NFT(serialNumber: numInItem + 1,
129                                              itemID: self.itemID)
130
131            // Increment the count of Collectibles minted for this Item
132            self.numberMintedPerItem = numInItem + 1
133
134            return <-newCollectible
135        }
136
137        // batchMintCollectible mints an arbitrary quantity of Collectibles
138        // and returns them as a Collection
139        //
140        // Parameters: itemID: the ID of the Item that the Collectibles are minted for
141        //             quantity: The quantity of Collectibles to be minted
142        //
143        // Returns: Collection object that contains all the Collectibles that were minted
144        //
145        pub fun batchMintCollectible(quantity: UInt64): @Collection {
146            let newCollection <- create Collection()
147
148            var i: UInt64 = 0
149            while i < quantity {
150                newCollection.deposit(token: <-self.mintCollectible())
151                i = i + 1
152            }
153
154            return <-newCollection
155        }
156
157        // Returns: the number of Collectibles
158        pub fun getNumberMinted(): UInt32 {
159            return self.numberMintedPerItem
160        }
161    }
162
163    // The structure holds metadata of an Collectible
164    pub struct CollectibleData {
165        // The ID of the Item that the Collectible references
166        pub let itemID: UInt32
167
168        // The place in the Item that this Collectible was minted
169        pub let serialNumber: UInt32
170
171        init(itemID: UInt32, serialNumber: UInt32) {
172            self.itemID = itemID
173            self.serialNumber = serialNumber
174        }
175    }
176
177    // The resource that represents the CollectibleData NFTs
178    //
179    pub resource NFT: NonFungibleToken.INFT, Anique.INFT {
180
181        // Global unique collectibleData ID
182        pub let id: UInt64
183
184        // Struct of Collectible metadata
185        pub let data: CollectibleData
186
187        init(serialNumber: UInt32, itemID: UInt32) {
188            // Increment the global Collectible IDs
189            SGKCLDR_cb_dinosaur2024.totalSupply = SGKCLDR_cb_dinosaur2024.totalSupply + 1
190
191            // set id
192            self.id = SGKCLDR_cb_dinosaur2024.totalSupply
193
194            // Set the metadata struct
195            self.data = CollectibleData(itemID: itemID, serialNumber: serialNumber)
196
197            emit CollectibleMinted(collectibleID: self.id, itemID: itemID, serialNumber: self.data.serialNumber)
198        }
199
200        destroy() {
201            emit CollectibleDestroyed(collectibleID: self.id)
202        }
203    }
204
205    // interface that represents SGKCLDR_cb_dinosaur2024 collections to public
206    // extends of NonFungibleToken.CollectionPublic
207    pub resource interface CollectionPublic {
208
209        pub fun deposit(token: @NonFungibleToken.NFT)
210        pub fun getIDs(): [UInt64]
211        pub fun borrowNFT(id: UInt64): &NonFungibleToken.NFT
212
213        // deposit multi tokens
214        pub fun batchDeposit(tokens: @Anique.Collection)
215
216        // contains NFT
217        pub fun contains(id: UInt64): Bool
218
219        // borrow NFT as SGKCLDR_cb_dinosaur2024 token
220        pub fun borrowSGKCLDR_cb_dinosaur2024Collectible(id: UInt64): auth &NFT
221    }
222
223    // Collection is a resource that every user who owns NFTs
224    // will store in their account to manage their NFTs
225    //
226    pub resource Collection: CollectionPublic, NonFungibleToken.Receiver, NonFungibleToken.Provider, NonFungibleToken.CollectionPublic {
227        // Dictionary of CollectibleData conforming tokens
228        // NFT is a resource type with a UInt64 ID field
229        pub var ownedNFTs: @{UInt64: NonFungibleToken.NFT}
230
231        init() {
232            self.ownedNFTs <- {}
233        }
234
235        // withdraw removes a Collectible from the Collection and moves it to the caller
236        //
237        // Parameters: withdrawID: The ID of the NFT
238        // that is to be removed from the Collection
239        //
240        // returns: @NonFungibleToken.NFT the token that was withdrawn
241        pub fun withdraw(withdrawID: UInt64): @NonFungibleToken.NFT {
242
243            // Remove the nft from the Collection
244            let token <- self.ownedNFTs.remove(key: withdrawID)
245                ?? panic("Cannot withdraw: Collectible does not exist in the collection")
246
247            emit Withdraw(id: token.id, from: self.owner?.address)
248
249            // Return the withdrawn token
250            return <- token
251        }
252
253        // batchWithdraw withdraws multiple tokens and returns them as a Collection
254        //
255        // Parameters: collectibleIds: An array of IDs to withdraw
256        //
257        // Returns: @NonFungibleToken.Collection: A collection that contains
258        //                                        the withdrawn collectibles
259        //
260        pub fun batchWithdraw(collectibleIds: [UInt64]): @Anique.Collection {
261            // Create a new empty Collection
262            var batchCollection <- create Collection()
263
264            // Iterate through the collectibleIds and withdraw them from the Collection
265            for collectibleID in collectibleIds {
266                batchCollection.deposit(token: <-self.withdraw(withdrawID: collectibleID))
267            }
268
269            // Return the withdrawn tokens
270            return <-batchCollection
271        }
272
273        // deposit takes a Collectible and adds it to the Collections dictionary
274        //
275        // Parameters: token: the NFT to be deposited in the collection
276        //
277        pub fun deposit(token: @NonFungibleToken.NFT) {
278
279            // Cast the deposited token as an SGKCLDR_cb_dinosaur2024 NFT to make sure
280            // it is the correct type
281            let token <- token as! @SGKCLDR_cb_dinosaur2024.NFT
282
283            // Get the token's ID
284            let id = token.id
285
286            // Add the new token to the dictionary
287            let oldToken <- self.ownedNFTs[id] <- token
288
289            // Only emit a deposit event if the Collection
290            // is in an account's storage
291            if self.owner?.address != nil {
292                emit Deposit(id: id, to: self.owner?.address)
293            }
294
295            // Destroy the empty old token that was "removed"
296            destroy oldToken
297        }
298
299        // batchDeposit takes a Collection object as an argument
300        // and deposits each contained NFT into this Collection
301        pub fun batchDeposit(tokens: @Anique.Collection) {
302
303            // Get an array of the IDs to be deposited
304            let keys = tokens.getIDs()
305
306            // Iterate through the keys in the collection and deposit each one
307            for key in keys {
308                self.deposit(token: <-tokens.withdraw(withdrawID: key))
309            }
310
311            // Destroy the empty Collection
312            destroy tokens
313        }
314
315        // getIDs returns an array of the IDs that are in the Collection
316        pub fun getIDs(): [UInt64] {
317            return self.ownedNFTs.keys
318        }
319
320        // contains returns whether ID is in the Collection
321        pub fun contains(id: UInt64): Bool {
322            return self.ownedNFTs[id] != nil
323        }
324
325        // borrowNFT Returns a borrowed reference to a Collectible in the Collection
326        // so that the caller can read its ID
327        //
328        // Parameters: id: The ID of the NFT to get the reference for
329        //
330        // Returns: A reference to the NFT
331        //
332        // Note: This only allows the caller to read the ID of the NFT,
333        // not any SGKCLDR_cb_dinosaur2024 specific data. Please use borrowCollectible to
334        // read Collectible data.
335        //
336        pub fun borrowNFT(id: UInt64): &NonFungibleToken.NFT {
337            return (&self.ownedNFTs[id] as &NonFungibleToken.NFT?)!
338        }
339
340        pub fun borrowAniqueNFT(id: UInt64): auth &Anique.NFT {
341            let nft = (&self.ownedNFTs[id] as auth &NonFungibleToken.NFT?)!
342            return nft as! auth &Anique.NFT
343        }
344
345        // borrowSGKCLDR_cb_dinosaur2024Collectible returns a borrowed reference
346        // to an SGKCLDR_cb_dinosaur2024 Collectible
347        pub fun borrowSGKCLDR_cb_dinosaur2024Collectible(id: UInt64): auth &NFT {
348            pre {
349                self.ownedNFTs[id] != nil: "NFT does not exist in the collection!"
350            }
351            let nft = (&self.ownedNFTs[id] as auth &NonFungibleToken.NFT?)!
352            return nft as! auth &NFT
353        }
354
355        // If a transaction destroys the Collection object,
356        // All the NFTs contained within are also destroyed!
357        //
358        destroy() {
359            destroy self.ownedNFTs
360        }
361    }
362
363    // Admin is a special authorization resource that
364    // allows the owner to perform important functions to modify the
365    // various aspects of the Items, CollectibleDatas, etc.
366    //
367    pub resource Admin {
368
369        // createItem creates a new Item struct
370        // and stores it in the Items dictionary field in the SGKCLDR_cb_dinosaur2024 smart contract
371        //
372        // Parameters: metadata: A dictionary mapping metadata titles to their data
373        //                       example: {"Title": "Excellent Anime", "Author": "John Smith"}
374        //
375        // Returns: the ID of the new Item object
376        //
377        pub fun createItem(metadata: {String: String}): UInt32 {
378            // Create the new Item
379            var newItem <- create Item(metadata: metadata)
380            let itemId = newItem.itemID
381
382            // Store it in the contract storage
383            SGKCLDR_cb_dinosaur2024.items[newItem.itemID] <-! newItem
384
385            return itemId
386        }
387
388        // borrowItem returns a reference to a Item in the SGKCLDR_cb_dinosaur2024
389        // contract so that the admin can call methods on it
390        //
391        // Parameters: itemID: The ID of the Item that you want to
392        // get a reference to
393        //
394        // Returns: A reference to the Item with all of the fields
395        // and methods exposed
396        //
397        pub fun borrowItem(itemID: UInt32): &Item {
398            pre {
399                SGKCLDR_cb_dinosaur2024.items[itemID] != nil: "Cannot borrow Item: The Item doesn't exist"
400            }
401
402            return (&SGKCLDR_cb_dinosaur2024.items[itemID] as &Item?)!
403        }
404
405        // createNewAdmin creates a new Admin resource
406        //
407        pub fun createNewAdmin(): @Admin {
408            return <-create Admin()
409        }
410    }
411
412    // -----------------------------------------------------------------------
413    // SGKCLDR_cb_dinosaur2024 contract-level function definitions
414    // -----------------------------------------------------------------------
415
416    // createEmptyCollection creates a new, empty Collection object so that
417    // a user can store it in their account storage.
418    // Once they have a Collection in their storage, they are able to receive
419    // Collectibles in transactions.
420    //
421    pub fun createEmptyCollection(): @NonFungibleToken.Collection {
422        return <-create SGKCLDR_cb_dinosaur2024.Collection()
423    }
424
425    // getNumCollectiblesInItem return the number of Collectibles that have been
426    //                        minted from a certain Item.
427    //
428    // Parameters: itemID: The id of the Item that is being searched
429    //
430    // Returns: The total number of Collectibles
431    //          that have been minted from a Item
432    pub fun getNumCollectiblesInItem(itemID: UInt32): UInt32 {
433        let item = (&SGKCLDR_cb_dinosaur2024.items[itemID] as &Item?)!
434        return item.numberMintedPerItem
435    }
436
437    // -----------------------------------------------------------------------
438    // SGKCLDR_cb_dinosaur2024 initialization function
439    // -----------------------------------------------------------------------
440    //
441    init() {
442        // Initialize contract fields
443        self.items <- {}
444        self.nextItemID = 1
445        self.totalSupply = 0
446
447        self.collectionStoragePath     = /storage/SGKCLDR_cb_dinosaur2024Collection
448        self.collectionPublicPath      =  /public/SGKCLDR_cb_dinosaur2024Collection
449        self.collectionPrivatePath     = /private/SGKCLDR_cb_dinosaur2024Collection
450        self.adminStoragePath          = /storage/SGKCLDR_cb_dinosaur2024Admin
451        self.saleCollectionStoragePath = /storage/SGKCLDR_cb_dinosaur2024SaleCollection
452        self.saleCollectionPublicPath  =  /public/SGKCLDR_cb_dinosaur2024SaleCollection
453
454        // Put a new Collection in storage
455        self.account.save<@Collection>(<- create Collection(), to: self.collectionStoragePath)
456
457        // Create a public capability for the Collection
458        self.account.link<&{CollectionPublic}>(self.collectionPublicPath, target: self.collectionStoragePath)
459
460        // Put the Admin in storage
461        self.account.save<@Admin>(<- create Admin(), to: self.adminStoragePath)
462
463        emit ContractInitialized()
464    }
465}
466