Smart Contract

SGKCLDRAAAB

A.70d460a972f408e0.SGKCLDRAAAB

Deployed

16h ago
Feb 28, 2026, 02:38:15 AM UTC

Dependents

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