Smart Contract
BBxBarbiePack
A.e5bf4d436ca23932.BBxBarbiePack
1/*
2*
3* This is an implemetation of a Flow Non-Fungible Token
4* It is not a part of the official standard but it is assumed to be
5* similar to how NFTs would implement the core functionality
6*
7*
8*/
9
10import NonFungibleToken from 0x1d7e57aa55817448
11import FungibleToken from 0xf233dcee88fe0abe
12import MetadataViews from 0x1d7e57aa55817448
13import ViewResolver from 0x1d7e57aa55817448
14
15access(all) contract BBxBarbiePack: NonFungibleToken {
16
17 /*
18 * NonFungibleToken Standard Events
19 */
20 access(all) event ContractInitialized()
21 access(all) event Withdraw(id: UInt64, from: Address?)
22 access(all) event Deposit(id: UInt64, to: Address?)
23
24 /*
25 * Project Events
26 */
27 access(all) event Mint(id: UInt64)
28 access(all) event Burn(id: UInt64)
29 access(all) event DepositEvent(
30 uuid: UInt64
31 , id: UInt64
32 , seriesId: UInt64
33 , editionId: UInt64
34 , to: Address?
35 )
36
37 access(all) event TransferEvent(
38 uuid: UInt64
39 , id: UInt64
40 , seriesId: UInt64
41 , editionId: UInt64
42 , to: Address?
43 )
44
45 /*
46 * Named Paths
47 */
48 access(all) let CollectionStoragePath: StoragePath
49 access(all) let CollectionPublicPath: PublicPath
50
51 /*
52 * NonFungibleToken Standard Fields
53 */
54 access(all) var totalSupply: UInt64
55
56 /*
57 * Pack State Variables
58 */
59 access(account) var name: String
60 access(account) var currentPackEditionIdByPackSeriesId: {UInt64: UInt64}
61
62
63 access(all) resource NFT: NonFungibleToken.NFT {
64 access(all) let id: UInt64
65 access(all) let packSeriesID: UInt64
66 access(all) let packEditionID: UInt64
67 access(all) let packHash: String
68 access(all) let metadata: {String: String}
69
70 access(all) view fun getViews(): [Type] {
71 return [
72 Type<MetadataViews.Display>(),
73 Type<MetadataViews.ExternalURL>(),
74 Type<MetadataViews.NFTCollectionData>(),
75 Type<MetadataViews.NFTCollectionDisplay>(),
76 Type<MetadataViews.Royalties>(),
77 Type<MetadataViews.Traits>()
78 ]
79 }
80
81
82 access(all) fun resolveView(_ view: Type): AnyStruct? {
83 switch view {
84 case Type<MetadataViews.Display>():
85 var ipfsImage = MetadataViews.IPFSFile(
86 cid: self.metadata["thumbnailCID"] ?? "No ThumnailCID set"
87 , path: self.metadata["thumbnailPath"] ?? "No ThumbnailPath set"
88 )
89 return MetadataViews.Display(
90 name: self.metadata["packName"]?.concat(" #")?.concat(self.packEditionID.toString()) ?? "Boss Beauties x Barbie Pack",
91 description: self.metadata["description"] ?? "Digital Pack Collectable from the Boss Beauties x Barbie collaboration" ,
92 thumbnail: ipfsImage
93 )
94
95 case Type<MetadataViews.ExternalURL>():
96 return MetadataViews.ExternalURL(
97 self.metadata["url"] ?? ""
98 )
99
100 case Type<MetadataViews.NFTCollectionData>():
101 return BBxBarbiePack.resolveContractView(resourceType: Type<@BBxBarbiePack.NFT>(), viewType: Type<MetadataViews.NFTCollectionData>())
102 case Type<MetadataViews.NFTCollectionDisplay>():
103 return BBxBarbiePack.resolveContractView(resourceType: Type<@BBxBarbiePack.NFT>(), viewType: Type<MetadataViews.NFTCollectionDisplay>())
104 case Type<MetadataViews.Traits>():
105 let excludedTraits = [
106 "thumbnailPath"
107 , "thumbnailCID"
108 , "collectionName"
109 , "collectionDescription"
110 , "description"
111 , "url"
112 ]
113 let traitsView = MetadataViews.dictToTraits(
114 dict: self.metadata
115 , excludedNames: excludedTraits
116 )
117 return traitsView
118 case Type<MetadataViews.Royalties>():
119 return BBxBarbiePack.resolveContractView(resourceType: Type<@BBxBarbiePack.NFT>(), viewType: Type<MetadataViews.Royalties>())
120 }
121
122 return nil
123 }
124
125
126 init(
127 id: UInt64
128 , packSeriesID: UInt64
129 , packEditionID: UInt64
130 , packHash: String
131 , metadata: {String: String}
132 ) {
133 self.id = id
134 self.packSeriesID = packSeriesID
135 self.packEditionID = packEditionID
136 self.packHash = packHash
137 self.metadata = metadata
138 emit Mint(id: self.packEditionID)
139 }
140
141
142 access(all) fun createEmptyCollection(): @{NonFungibleToken.Collection} {
143 return <-BBxBarbiePack.createEmptyCollection(nftType: Type<@BBxBarbiePack.NFT>())
144 }
145 }
146
147 access(all) resource interface PackCollectionPublic {}
148
149 access(all) resource Collection: PackCollectionPublic, NonFungibleToken.Collection {
150 access(all) var ownedNFTs: @{UInt64: {NonFungibleToken.NFT}}
151
152 init() {
153 self.ownedNFTs <- {}
154 }
155
156
157 /// getSupportedNFTTypes returns a list of NFT types that this receiver accepts
158 access(all) view fun getSupportedNFTTypes(): {Type: Bool} {
159 let supportedTypes: {Type: Bool} = {}
160 supportedTypes[Type<@BBxBarbiePack.NFT>()] = true
161 return supportedTypes
162 }
163
164 /// Returns whether or not the given type is accepted by the collection
165 /// A collection that can accept any type should just return true by default
166 access(all) view fun isSupportedNFTType(type: Type): Bool {
167 return type == Type<@BBxBarbiePack.NFT>()
168 }
169
170 access(NonFungibleToken.Withdraw) fun withdraw(withdrawID: UInt64): @{NonFungibleToken.NFT} {
171 let BBxBarbiePack <- self.ownedNFTs.remove(
172 key: withdrawID
173 ) ?? panic("missing NFT")
174 emit Withdraw(
175 id: BBxBarbiePack.id,
176 from: self.owner?.address
177 )
178 return <-BBxBarbiePack
179 }
180
181 access(all) fun deposit(
182 token: @{NonFungibleToken.NFT}
183 ) {
184 let BBxBarbiePack <- token as! @BBxBarbiePack.NFT
185 let BBxBarbiePackUUID: UInt64 = BBxBarbiePack.uuid
186 let BBxBarbiePackSeriesId: UInt64 = BBxBarbiePack.packSeriesID
187 let BBxBarbiePackID: UInt64 = BBxBarbiePack.id
188 let BBxBarbiePackEditionID: UInt64 = BBxBarbiePack.packEditionID
189 self.ownedNFTs[BBxBarbiePackID] <-! BBxBarbiePack
190 emit Deposit(
191 id: BBxBarbiePackID,
192 to: self.owner?.address
193 )
194 emit DepositEvent(
195 uuid:BBxBarbiePackUUID
196 , id: BBxBarbiePackID
197 , seriesId: BBxBarbiePackSeriesId
198 , editionId: BBxBarbiePackEditionID
199 , to: self.owner?.address
200 )
201 }
202
203 access(all) view fun getIDs(): [UInt64] {
204 return self.ownedNFTs.keys
205 }
206
207
208 access(all) view fun getLength(): Int {
209 return self.ownedNFTs.keys.length
210 }
211
212
213 access(all) view fun borrowNFT(_ id: UInt64): &{NonFungibleToken.NFT}?{
214 return (&self.ownedNFTs[id])
215 }
216
217 access(all) fun borrowPack(id: UInt64): &NFT? {
218 if let tokenRef: &{NonFungibleToken.NFT} = &self.ownedNFTs[id] {
219 return tokenRef as! &NFT
220 } else {
221 return nil
222 }
223 }
224
225 access(all) view fun borrowViewResolver(id: UInt64): &{ViewResolver.Resolver}? {
226 if let nftRef: &{NonFungibleToken.NFT} = &self.ownedNFTs[id] {
227 return nftRef as &{ViewResolver.Resolver}
228 }
229 return nil
230 }
231
232
233 /// Allows a given function to iterate through the list
234 /// of owned NFT IDs in a collection without first
235 /// having to load the entire list into memory
236 access(all) fun forEachID(_ f: fun(UInt64): Bool) {
237 self.ownedNFTs.forEachKey(f)
238 }
239
240
241 access(all) fun createEmptyCollection(): @{NonFungibleToken.Collection} {
242 return <- BBxBarbiePack.createEmptyCollection(nftType: Type<@BBxBarbiePack.NFT>())
243 }
244 }
245
246 /*
247 * Public Functions
248 */
249
250 access(all) fun createEmptyCollection(nftType: Type): @{NonFungibleToken.Collection} {
251 return <- create Collection()
252 }
253
254 access(all) fun getTotalSupply(): UInt64 {
255 return self.totalSupply
256 }
257
258
259 access(all) fun getName(): String {
260 return self.name
261 }
262
263 access(all) fun transfer(uuid: UInt64, id: UInt64, packSeriesId: UInt64, packEditionId: UInt64, toAddress: Address){
264
265 let BBxBarbiePackV2UUID: UInt64 = uuid
266 let BBxBarbiePackV2SeriesId: UInt64 = packSeriesId
267 let BBxBarbiePackV2ID: UInt64 = id
268 let BBxBarbiePackV2packEditionID: UInt64 = packEditionId
269
270 emit TransferEvent(
271 uuid: BBxBarbiePackV2UUID
272 , id: BBxBarbiePackV2ID
273 , seriesId: BBxBarbiePackV2SeriesId
274 , editionId: BBxBarbiePackV2packEditionID
275 , to: toAddress)
276 }
277
278access(all) view fun getContractViews(resourceType: Type?): [Type] {
279 return [
280 Type<MetadataViews.NFTCollectionData>(),
281 Type<MetadataViews.NFTCollectionDisplay>(),
282 Type<MetadataViews.Royalties>()
283 ]
284}
285
286access(all) view fun resolveContractView(resourceType: Type?, viewType: Type): AnyStruct?{
287 switch viewType {
288 case Type<MetadataViews.NFTCollectionData>():
289 return MetadataViews.NFTCollectionData(
290 storagePath: BBxBarbiePack.CollectionStoragePath,
291 publicPath: BBxBarbiePack.CollectionPublicPath,
292 publicCollection: Type<&BBxBarbiePack.Collection>(),
293 publicLinkedType: Type<&BBxBarbiePack.Collection>(),
294 createEmptyCollectionFunction: fun(): @{NonFungibleToken.Collection} {return <- BBxBarbiePack.createEmptyCollection(nftType: Type<@BBxBarbiePack.NFT>())
295 })
296
297 case Type<MetadataViews.NFTCollectionDisplay>():
298 let externalURL = MetadataViews.ExternalURL(
299 "https://www.mattel.com/"
300 )
301 let squareImage = MetadataViews.Media(
302 file: MetadataViews.HTTPFile(
303 url: "https://www.mattel.com/"
304 ),
305 mediaType: "image/png")
306 let bannerImage = MetadataViews.Media(
307 file: MetadataViews.HTTPFile(
308 url: "https://www.mattel.com/"
309 ),
310 mediaType: "image/png")
311 let socialMap: {String: MetadataViews.ExternalURL} = {
312 "facebook": MetadataViews.ExternalURL(
313 "https://www.facebook.com/mattel"
314 ),
315 "instagram": MetadataViews.ExternalURL(
316 "https://www.instagram.com/mattel"
317 ),
318 "twitter": MetadataViews.ExternalURL(
319 "https://www.twitter.com/mattel"
320 )
321 }
322 return MetadataViews.NFTCollectionDisplay(
323 name: "Boss Beauties x Barbie Pack",
324 description: "Digital Collectable from the Boss Beauties x Barbie collaboration",
325 externalURL: externalURL,
326 squareImage: squareImage,
327 bannerImage: bannerImage,
328 socials: socialMap
329 )
330 case Type<MetadataViews.Royalties>():
331 let flowReciever = getAccount(0xf86e2f015cd692be).capabilities.get<&{FungibleToken.Receiver}>(/public/flowTokenReceiver)
332 return MetadataViews.Royalties([
333 MetadataViews.Royalty(
334 receiver:flowReciever
335 , cut: 0.05
336 , description: "Mattel 5% Royalty")
337 ]
338 )
339
340 }
341 return nil
342}
343
344 /*
345 * Admin Functions
346 */
347 access(account) fun addNewSeries(newPackSeriesID: UInt64){
348 self.currentPackEditionIdByPackSeriesId.insert(key: newPackSeriesID, 0)
349 }
350
351
352 access(account) fun updateCurrentEditionIdByPackSeriesId(packSeriesID: UInt64, packSeriesEdition: UInt64){
353 self.currentPackEditionIdByPackSeriesId[packSeriesID] = packSeriesEdition
354 }
355
356
357 access(account) fun mint(
358 nftID: UInt64
359 , packEditionID: UInt64
360 , packSeriesID: UInt64
361 , packHash: String
362 , metadata: {String: String}
363 ): @{NonFungibleToken.NFT} {
364 self.totalSupply = self.totalSupply + 1
365 self.currentPackEditionIdByPackSeriesId[packSeriesID] = self.currentPackEditionIdByPackSeriesId[packSeriesID]! + 1
366 return <- create NFT(
367 id: nftID
368 , packSeriesID: packSeriesID
369 , packEditionID: self.currentPackEditionIdByPackSeriesId[packSeriesID]!
370 , packHash: packHash
371 , metadata: metadata
372 )
373 }
374
375
376
377 // initialize contract state variables
378 init(){
379 self.name = "Boss Beauties x Barbie Pack"
380 self.totalSupply = 0
381 self.currentPackEditionIdByPackSeriesId = {1 : 0}
382
383 // set the named paths
384 self.CollectionStoragePath = /storage/BBxBarbiePackCollection
385 self.CollectionPublicPath = /public/BBxBarbiePackCollection
386
387 // create a collection resource and save it to storage
388 let collection: @BBxBarbiePack.Collection <- create Collection()
389 self.account.storage.save(<-collection, to: self.CollectionStoragePath)
390
391 let collectionCap = self.account.capabilities.storage.issue<&BBxBarbiePack.Collection>(self.CollectionStoragePath)
392 self.account.capabilities.publish(collectionCap, at: self.CollectionPublicPath)
393
394 emit ContractInitialized()
395 }
396
397}
398