Smart Contract

DisruptArt

A.cd946ef9b13804c6.DisruptArt

Deployed

2h ago
Mar 01, 2026, 03:16:28 AM UTC

Dependents

0 imports
1// DisruptArt NFT Marketplace
2// NFT smart contract
3// NFT Marketplace : www.disrupt.art
4// Owner           : Disrupt Art, INC.
5// Developer       : www.blaze.ws
6// Version         : 0.0.8
7// Blockchain      : Flow www.onFlow.org
8
9import NonFungibleToken from 0x1d7e57aa55817448
10import MetadataViews from 0x1d7e57aa55817448
11import FungibleToken from 0xf233dcee88fe0abe
12
13pub contract DisruptArt: NonFungibleToken {
14   
15    // Total number of token supply
16    pub var totalSupply: UInt64
17
18    // NFT No of Editions(Multiple copies) limit
19    pub var editionLimit: UInt
20
21    /// Path where the `Collection` is stored
22    pub let disruptArtStoragePath: StoragePath
23
24    /// Path where the public capability for the `Collection` is
25    pub let disruptArtPublicPath: PublicPath
26
27    /// NFT Minter
28    pub let disruptArtMinterPath: StoragePath
29    
30    // Contract Events
31    pub event ContractInitialized()
32    pub event Withdraw(id: UInt64, from: Address?)
33    pub event Deposit(id: UInt64, to: Address?)
34    pub event Mint(id: UInt64, content:String, owner: Address?, name:String)
35    pub event GroupMint(id: UInt64, content:String, owner: Address?, name:String, tokenGroupId: UInt64 )
36
37
38    // TOKEN RESOURCE
39    pub resource NFT: NonFungibleToken.INFT, MetadataViews.Resolver {
40
41        // Unique identifier for NFT Token
42        pub let id :UInt64
43
44        // Meta data to store token data (use dict for data)
45        access(self) let metaData: {String : String}
46        
47        pub fun getMetadata():{String: String} {
48            return self.metaData
49        }
50
51        // NFT token name
52        pub let name:String
53
54        // NFT token creator address
55        pub let creator:Address?
56
57        // In current store static dict in meta data
58        init( id : UInt64, content : String, name:String, description:String , creator:Address?,previewContent:String,mimeType:String) {
59            self.id = id
60            self.metaData = {"content" : content, "description": description, "previewContent":previewContent, "mimeType":mimeType }
61            self.creator = creator
62            self.name = name
63        }
64
65        access(self) fun getFlowRoyaltyReceiverPublicPath(): PublicPath {
66	     return /public/flowTokenReceiver
67        }
68
69
70        // fn to get the royality details
71        access(self) fun genRoyalities():[MetadataViews.Royalty] {
72
73            var royalties:[MetadataViews.Royalty] = []             
74
75            // Creator Royalty
76            royalties.append(
77                MetadataViews.Royalty(
78                    receiver: getAccount(self.creator!).getCapability<&FungibleToken.Vault{FungibleToken.Receiver}>(self.getFlowRoyaltyReceiverPublicPath()),
79                    cut: UFix64(0.1),
80                    description: "Creator Royalty"
81                )
82            )
83
84            return royalties
85        }
86        
87        pub fun getViews(): [Type] {
88            return [
89                Type<MetadataViews.Display>(),
90                Type<MetadataViews.Royalties>(),
91                Type<MetadataViews.ExternalURL>(),
92                Type<MetadataViews.NFTCollectionData>(),
93                Type<MetadataViews.NFTCollectionDisplay>(),
94                Type<MetadataViews.Serial>(),
95                Type<MetadataViews.Traits>()
96            ]
97        }
98
99        pub fun resolveView(_ view: Type): AnyStruct? {
100            switch view {
101                case Type<MetadataViews.Display>():
102                    return MetadataViews.Display(
103                        name: self.name,
104                        description: self.metaData["description"]!,
105                        thumbnail: MetadataViews.HTTPFile(
106                            url: self.metaData["previewContent"]!
107                        )
108                    )
109                case Type<MetadataViews.Serial>():
110                    return MetadataViews.Serial(
111                        self.id
112                    )
113                case Type<MetadataViews.Royalties>():
114                    return MetadataViews.Royalties(
115                        self.genRoyalities()
116                    )
117                case Type<MetadataViews.ExternalURL>():
118                    return MetadataViews.ExternalURL("https://disrupt.art")
119                case Type<MetadataViews.NFTCollectionData>():
120                    return MetadataViews.NFTCollectionData(
121                        storagePath: DisruptArt.disruptArtStoragePath,
122                        publicPath: DisruptArt.disruptArtPublicPath,
123                        providerPath: /private/DisruptArtNFTCollection,
124                        publicCollection: Type<&DisruptArt.Collection{DisruptArt.DisruptArtCollectionPublic}>(),
125                        publicLinkedType: Type<&DisruptArt.Collection{DisruptArt.DisruptArtCollectionPublic,NonFungibleToken.CollectionPublic,NonFungibleToken.Receiver,MetadataViews.ResolverCollection}>(),
126                        providerLinkedType: Type<&DisruptArt.Collection{DisruptArt.DisruptArtCollectionPublic,NonFungibleToken.CollectionPublic,NonFungibleToken.Provider,MetadataViews.ResolverCollection}>(),
127                        createEmptyCollectionFunction: (fun (): @NonFungibleToken.Collection {
128                            return <-DisruptArt.createEmptyCollection()
129                        })
130                    )
131                case Type<MetadataViews.NFTCollectionDisplay>():
132                    let media = MetadataViews.Media(
133                        file: MetadataViews.HTTPFile(
134                            url: "https://disrupt.art/nft/assets/images/logoicon.png"
135                        ),
136                        mediaType: "image/png"
137                    )
138                    return MetadataViews.NFTCollectionDisplay(
139                        name: "DisruptArt Collection",
140                        description: "Discover amazing NFT collections from various disruptor creators. Disrupt.art Marketplace's featured and spotlight NFTs",
141                        externalURL: MetadataViews.ExternalURL("https://disrupt.art"),
142                        squareImage: media,
143                        bannerImage: media,
144                        socials: {
145                            "twitter": MetadataViews.ExternalURL("https://twitter.com/DisruptArt"),
146                            "instagram": MetadataViews.ExternalURL("https://www.instagram.com/disrupt.art/"),
147                            "discord" : MetadataViews.ExternalURL("https://discord.io/disruptart")
148                        }
149                    )
150                case Type<MetadataViews.Traits>():
151                    return []
152            }
153            return nil
154        }
155
156    }
157
158    // Account's public collection
159    pub resource interface DisruptArtCollectionPublic {
160
161        pub fun deposit(token:@NonFungibleToken.NFT)
162
163        pub fun getIDs(): [UInt64]
164
165        pub fun borrowNFT(id: UInt64): &NonFungibleToken.NFT
166        
167        pub fun borrowDisruptArt(id: UInt64): &DisruptArt.NFT? {
168            // If the result isn't nil, the id of the returned reference
169            // should be the same as the argument to the function
170            post {
171                (result == nil) || (result?.id == id):
172                    "Cannot borrow CaaPass reference: The ID of the returned reference is incorrect"
173            }
174        }
175
176    } 
177
178    // NFT Collection resource
179    pub resource Collection : DisruptArtCollectionPublic, NonFungibleToken.Provider, NonFungibleToken.Receiver, NonFungibleToken.CollectionPublic, MetadataViews.ResolverCollection {
180        
181        // Contains caller's list of NFTs
182        pub var ownedNFTs: @{UInt64 : NonFungibleToken.NFT}
183
184        init() {
185            self.ownedNFTs <- {}
186        }
187
188        pub fun deposit(token: @NonFungibleToken.NFT) {
189
190            let token <- token as! @DisruptArt.NFT
191
192            let id: UInt64 = token.id
193
194            // add the new token to the dictionary which removes the old one
195            let oldToken <- self.ownedNFTs[id] <- token
196
197            emit Deposit(id: id, to: self.owner?.address)
198
199            destroy oldToken
200        }
201
202        // function returns token keys of owner
203        pub fun getIDs():[UInt64] {
204            return self.ownedNFTs.keys
205        }
206
207        // function returns token data of token id
208        pub fun borrowNFT(id: UInt64): &NonFungibleToken.NFT {
209            return (&self.ownedNFTs[id] as &NonFungibleToken.NFT?)!
210        }
211        
212        // Gets a reference to an NFT in the collection as a DisruptArt
213        pub fun borrowDisruptArt(id: UInt64): &DisruptArt.NFT? {
214            if self.ownedNFTs[id] != nil {
215                let ref = (&self.ownedNFTs[id] as auth &NonFungibleToken.NFT?)!
216                return ref as! &DisruptArt.NFT
217            } else {
218                return nil
219            }
220        }
221
222        // function to check wether the owner have token or not
223        pub fun tokenExists(id:UInt64) : Bool {
224            return self.ownedNFTs[id] != nil
225        }
226
227        pub fun withdraw(withdrawID:UInt64) : @NonFungibleToken.NFT {
228            
229            let token <- self.ownedNFTs.remove(key: withdrawID) ?? panic("missing NFT")
230
231            emit Withdraw(id: token.id, from: self.owner?.address)
232
233            return <-token    
234        }
235
236        pub fun borrowViewResolver(id: UInt64): &AnyResource{MetadataViews.Resolver} {
237            let nft = (&self.ownedNFTs[id] as auth &NonFungibleToken.NFT?)!
238            let DisruptArtNFT = nft as! &DisruptArt.NFT
239            return DisruptArtNFT as &AnyResource{MetadataViews.Resolver}
240        }
241
242        destroy(){
243            destroy self.ownedNFTs
244        }
245
246    }
247
248    // NFT MINTER
249    pub resource NFTMinter {
250
251        // Function to mint group of tokens
252        pub fun GroupMint(recipient: &{DisruptArtCollectionPublic},content:String, description:String, name:String, edition:UInt, tokenGroupId:UInt64, previewContent:String, mimeType:String) {
253            pre {
254                DisruptArt.editionLimit >= edition : "Edition count exceeds the limit"
255                edition >=2 : "Edition count should be greater than or equal to 2"
256            }
257            var count = 0 as UInt
258            
259            while count < edition {
260                let token <- create NFT(id: DisruptArt.totalSupply, content:content, name:name, description:description, creator: recipient.owner?.address,previewContent:previewContent,mimeType:mimeType)
261                emit GroupMint(id:DisruptArt.totalSupply,content:content,owner: recipient.owner?.address, name:name, tokenGroupId:tokenGroupId)
262                recipient.deposit(token: <- token)
263                DisruptArt.totalSupply = DisruptArt.totalSupply + 1 as UInt64
264                count = count + 1
265            }
266        }
267
268        pub fun Mint(recipient: &{DisruptArtCollectionPublic},content:String, name:String, description:String,previewContent:String,mimeType:String ) {
269            let token <- create NFT(id: DisruptArt.totalSupply, content:content, name:name, description:description, creator: recipient.owner?.address,previewContent:previewContent, mimeType:mimeType)
270            emit Mint(id:DisruptArt.totalSupply,content:content,owner: recipient.owner?.address, name:name)
271            recipient.deposit(token: <- token)
272            DisruptArt.totalSupply = DisruptArt.totalSupply + 1 as UInt64
273        } 
274    }
275
276    // This is used to create the empty collection. without this address cannot access our NFT token
277    pub fun createEmptyCollection(): @NonFungibleToken.Collection {
278        return <- create DisruptArt.Collection()
279    }
280    // Admin can change the maximum supported group minting count limit for the platform. Currently it is 50
281    pub resource Admin {
282        pub fun changeLimit(limit:UInt) {
283            DisruptArt.editionLimit = limit
284        }
285    }
286
287    // Contract init
288    init() {
289
290        // total supply is zero at the time of contract deployment
291        self.totalSupply = 0
292
293        self.editionLimit = 10000
294
295        self.disruptArtStoragePath = /storage/DisruptArtNFTCollection
296
297        self.disruptArtPublicPath = /public/DisruptArtNFTPublicCollection
298
299        self.disruptArtMinterPath = /storage/DisruptArtNFTMinter
300
301        self.account.save(<-self.createEmptyCollection(), to: self.disruptArtStoragePath)
302
303        self.account.link<&{DisruptArtCollectionPublic}>(self.disruptArtPublicPath, target:self.disruptArtStoragePath)
304
305        self.account.save(<-create self.Admin(), to: /storage/DirsuptArtAdmin)
306
307        // store a minter resource in account storage
308        self.account.save(<-create NFTMinter(), to: self.disruptArtMinterPath)
309
310        emit ContractInitialized()
311
312    }
313
314}
315
316