Smart Contract

CharityNFT

A.097bafa4e0b48eef.CharityNFT

Valid From

86,041,844

Deployed

3d ago
Feb 24, 2026, 11:57:41 PM UTC

Dependents

20 imports
1
2import NonFungibleToken from 0x1d7e57aa55817448
3import MetadataViews from 0x1d7e57aa55817448
4import ViewResolver from 0x1d7e57aa55817448
5
6access(all) contract CharityNFT: NonFungibleToken {
7
8    access(all) var totalSupply: UInt64
9
10    access(all) let CollectionStoragePath: StoragePath
11    access(all) let CollectionPublicPath: PublicPath
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    access(all) event Minted(id: UInt64, metadata: {String:String}, to:Address)
17
18    access(all) resource NFT: NonFungibleToken.NFT, Public, ViewResolver.Resolver {
19        access(all) let id: UInt64
20
21        access(self) let metadata: {String: String}
22
23        init(initID: UInt64, metadata: {String : String}) {
24            self.id = initID
25            self.metadata = metadata
26        }
27
28        access(all) view fun getMetadata() : { String : String} {
29            return self.metadata
30        }
31
32        access(all) view fun getID(): UInt64 {
33            return self.id
34        }
35
36        access(all) view fun getViews(): [Type] {
37            return [
38            Type<MetadataViews.Display>() ,
39            Type<MetadataViews.Royalties>() ,
40            Type<MetadataViews.ExternalURL>() ,
41            Type<MetadataViews.NFTCollectionDisplay>() ,
42            Type<MetadataViews.NFTCollectionData>() , 
43            Type<MetadataViews.Edition>()
44            ]
45        }
46
47        access(all) fun createEmptyCollection(): @{NonFungibleToken.Collection} {
48            return <-CharityNFT.createEmptyCollection(nftType:Type<@CharityNFT.NFT>())
49        }
50
51        access(all) fun resolveView(_ view: Type): AnyStruct? {
52            switch view {
53
54                case Type<MetadataViews.Display>() : 
55                // just in case there is no "image" key, return the general bronze image
56                let image = self.metadata["thumbnail"] ?? "ipfs://QmcxXHLADpcw5R7xi6WmPjnKAEayK3eiEh85gzjgdzfwN6"
57                return MetadataViews.Display(
58                    name: self.metadata["name"] ?? "Neo Charity 2021" ,
59                    description: self.metadata["description"] ?? "Neo Charity 2021",
60                    thumbnail: MetadataViews.IPFSFile(
61                        cid: image.slice(from: "ipfs://".length, upTo: image.length) , 
62                        path: nil
63                    )
64                )
65
66                case Type<MetadataViews.Royalties>() : 
67                // No Royalties implemented
68                return MetadataViews.Royalties([])
69
70                case Type<MetadataViews.ExternalURL>() : 
71                return MetadataViews.ExternalURL("http://find.xyz/neoCharity")
72
73                case Type<MetadataViews.NFTCollectionDisplay>() : 
74                return MetadataViews.NFTCollectionDisplay(
75                    name: "Neo Charity 2021",
76                    description: "This collection is to show participation in the Neo Collectibles x Flowverse Charity Auction in 2021.",
77                    externalURL: MetadataViews.ExternalURL("http://find.xyz/neoCharity"),
78                    squareImage: MetadataViews.Media(file: MetadataViews.HTTPFile(url: "https://pbs.twimg.com/profile_images/1467546091780550658/R1uc6dcq_400x400.jpg") , mediaType: "image"),
79                    bannerImage: MetadataViews.Media(file: MetadataViews.HTTPFile(url: "https://pbs.twimg.com/profile_banners/1448245049666510848/1652452073/1500x500") , mediaType: "image"),
80                    socials: { 
81                        "Twitter" : MetadataViews.ExternalURL("https://twitter.com/findonflow") , 
82                        "Discord" : MetadataViews.ExternalURL("https://discord.gg/95P274mayM") 
83                    }
84                )
85
86                case Type<MetadataViews.NFTCollectionData>() : 
87                return CharityNFT.resolveContractView(resourceType: Type<@CharityNFT.Collection>(), viewType: Type<MetadataViews.NFTCollectionData>()) as! MetadataViews.NFTCollectionData
88
89                case Type<MetadataViews.Edition>() : 
90                let edition = self.metadata["edition"] 
91                let maxEdition = self.metadata["maxEdition"] 
92                if edition == nil || maxEdition == nil {
93                    return nil
94                }
95                let editionNumber = self.parseUInt64(edition!)
96                let maxEditionNumber = self.parseUInt64(maxEdition!)
97                if editionNumber == nil {
98                    return nil
99                }
100                return MetadataViews.Edition(
101                    name: nil, 
102                    number: editionNumber!, 
103                    max: editionNumber
104                )
105
106            }
107            return nil
108
109        }
110
111        access(all) view fun parseUInt64(_ string: String) : UInt64? {
112            let chars : {Character : UInt64} = {
113                "0" : 0 , 
114                "1" : 1 , 
115                "2" : 2 , 
116                "3" : 3 , 
117                "4" : 4 , 
118                "5" : 5 , 
119                "6" : 6 , 
120                "7" : 7 , 
121                "8" : 8 , 
122                "9" : 9 
123            }
124            var number : UInt64 = 0
125            var i = 0
126            while i < string.length {
127                if let n = chars[string[i]] {
128                    number = number * 10 + n
129                } else {
130                    return nil 
131                }
132                i = i + 1
133            }
134            return number 
135        }
136
137    }
138
139    access(all) view fun getContractViews(resourceType: Type?): [Type] {
140        return [
141        Type<MetadataViews.NFTCollectionData>(),
142        Type<MetadataViews.NFTCollectionDisplay>() 
143        ]
144    }
145
146    access(all) fun resolveContractView(resourceType: Type?, viewType: Type): AnyStruct? {
147        switch viewType {
148
149            case Type<MetadataViews.NFTCollectionDisplay>() : 
150            return MetadataViews.NFTCollectionDisplay(
151                name: "Neo Charity 2021",
152                description: "This collection is to show participation in the Neo Collectibles x Flowverse Charity Auction in 2021.",
153                externalURL: MetadataViews.ExternalURL("http://find.xyz/neoCharity"),
154                squareImage: MetadataViews.Media(file: MetadataViews.HTTPFile(url: "https://pbs.twimg.com/profile_images/1467546091780550658/R1uc6dcq_400x400.jpg") , mediaType: "image"),
155                bannerImage: MetadataViews.Media(file: MetadataViews.HTTPFile(url: "https://pbs.twimg.com/profile_banners/1448245049666510848/1652452073/1500x500") , mediaType: "image"),
156                socials: { 
157                    "Twitter" : MetadataViews.ExternalURL("https://twitter.com/findonflow") , 
158                    "Discord" : MetadataViews.ExternalURL("https://discord.gg/95P274mayM") 
159                }
160            )
161
162        case Type<MetadataViews.NFTCollectionData>():
163            let collectionData = MetadataViews.NFTCollectionData(
164                storagePath: CharityNFT.CollectionStoragePath,
165                publicPath: CharityNFT.CollectionPublicPath,
166                publicCollection: Type<&CharityNFT.Collection>(),
167                publicLinkedType: Type<&CharityNFT.Collection>(),
168                createEmptyCollectionFunction: (fun(): @{NonFungibleToken.Collection} {
169                    return <-CharityNFT.createEmptyCollection(nftType:Type<@CharityNFT.NFT>())
170                })
171            )
172            return collectionData
173        }
174        return nil
175    }
176
177    //The public interface can show metadata and the content for the Art piece
178    access(all) resource interface Public {
179        access(all) let id: UInt64
180        access(all) view fun getMetadata() : {String : String}
181    }
182
183    //Standard NFT collectionPublic interface that can also borrowArt as the correct type
184    access(all) resource interface CollectionPublic {
185        access(all) fun deposit(token: @{NonFungibleToken.NFT})
186        access(all) view fun getIDs(): [UInt64]
187        access(all) view fun borrowNFT(_ id: UInt64): &{NonFungibleToken.NFT}?
188        access(all) fun borrowCharity(id: UInt64): &{Public}?
189    }
190
191    access(all) resource Collection: NonFungibleToken.Collection, CollectionPublic , ViewResolver.ResolverCollection{
192        // dictionary of NFT conforming tokens
193        // NFT is a resource type with an `UInt64` ID field
194        access(all) var ownedNFTs: @{UInt64: {NonFungibleToken.NFT}}
195
196        init () {
197            self.ownedNFTs <- {}
198            let identifier = "charityNFTCollection"
199        }
200
201        // withdraw removes an NFT from the collection and moves it to the caller
202        access(NonFungibleToken.Withdraw) fun withdraw(withdrawID: UInt64): @{NonFungibleToken.NFT} {
203            let token <- self.ownedNFTs.remove(key: withdrawID) ?? panic("missing NFT. WithdrawID : ".concat(withdrawID.toString()))
204
205            emit Withdraw(id: token.id, from: self.owner?.address)
206
207            return <-token
208        }
209
210        // deposit takes a NFT and adds it to the collections dictionary
211        // and adds the ID to the id array
212        access(all) fun deposit(token: @{NonFungibleToken.NFT}) {
213            let token <- token as! @CharityNFT.NFT
214
215            let id: UInt64 = token.id
216
217            // add the new token to the dictionary which removes the old one
218            let oldToken <- self.ownedNFTs[id] <- token
219
220            emit Deposit(id: id, to: self.owner?.address)
221
222            destroy oldToken
223        }
224
225        // getIDs returns an array of the IDs that are in the collection
226        access(all) view fun getIDs(): [UInt64] {
227            return self.ownedNFTs.keys
228        }
229
230        // borrowNFT gets a reference to an NFT in the collection
231        // so that the caller can read its metadata and call its methods
232        access(all) view fun borrowNFT(_ id: UInt64): &{NonFungibleToken.NFT}? {
233            return (&self.ownedNFTs[id] as &{NonFungibleToken.NFT}?)!
234        }
235
236        //borrow charity
237        access(all) fun borrowCharity(id: UInt64): &{CharityNFT.Public}? {
238            if self.ownedNFTs[id] != nil {
239                let ref = (&self.ownedNFTs[id] as &{NonFungibleToken.NFT}?)!
240                return ref as! &NFT
241            } else {
242                return nil
243            }
244        }
245
246        //borrow view resolver
247        access(all) view fun borrowViewResolver(id: UInt64): &{ViewResolver.Resolver} {
248            if self.ownedNFTs[id] == nil {
249                panic("NFT does not exist. ID : ".concat(id.toString()))
250            }
251
252            let nft = (&self.ownedNFTs[id] as &{NonFungibleToken.NFT}?)!
253            return nft as! &CharityNFT.NFT
254        }
255
256        /// getSupportedNFTTypes returns a list of NFT types that this receiver accepts
257        access(all) view fun getSupportedNFTTypes(): {Type: Bool} {
258            let supportedTypes: {Type: Bool} = {}
259            supportedTypes[Type<@CharityNFT.NFT>()] = true
260            return supportedTypes
261        }
262
263        /// Returns whether or not the given type is accepted by the collection
264        /// A collection that can accept any type should just return true by default
265        access(all) view fun isSupportedNFTType(type: Type): Bool {
266            if type == Type<@CharityNFT.NFT>() {
267                return true
268            } else {
269                return false
270            }
271        }
272
273        access(all) fun createEmptyCollection(): @{NonFungibleToken.Collection} {
274            return <- create CharityNFT.Collection()
275        }
276
277        access(all) view fun getLength(): Int {
278            return self.ownedNFTs.keys.length
279        }
280    }
281
282    // public function that anyone can call to create a new empty collection
283    access(all) fun createEmptyCollection(nftType:Type): @{NonFungibleToken.Collection} {
284        return <- create Collection()
285    }
286
287
288    // mintNFT mints a new NFT with a new ID
289    // and deposit it in the recipients collection using their collection reference
290    access(account) fun mintCharity(metadata: {String:String}, recipient: Capability<&{NonFungibleToken.Collection}>) {
291        // create a new NFT
292        var newNFT <- create NFT(initID: CharityNFT.totalSupply, metadata:metadata)
293
294        // deposit it in the recipient's account using their reference
295        let collectionRef = recipient.borrow() ?? panic("Cannot borrow reference to collection public. ")
296        collectionRef.deposit(token: <-newNFT)
297        emit Minted(id: CharityNFT.totalSupply, metadata:metadata, to: recipient.address)
298
299        CharityNFT.totalSupply = CharityNFT.totalSupply + 1 
300    }
301
302    init() {
303        // Initialize the total supply
304        self.totalSupply = 0
305
306        emit ContractInitialized()
307        self.CollectionPublicPath=/public/findCharityCollection
308        self.CollectionStoragePath=/storage/findCharityCollection
309    }
310}
311
312