Smart Contract
Boast
A.440776a8205e9f80.Boast
1import NonFungibleToken from 0x1d7e57aa55817448
2import MetadataViews from 0x1d7e57aa55817448
3import ViewResolver from 0x1d7e57aa55817448
4
5access(all) contract Boast: NonFungibleToken {
6 access(all) event ContractInitialized()
7 access(all) event Withdraw(id: UInt64, from: Address?)
8 access(all) event Deposit(id: UInt64, to: Address?)
9 access(all) event PublishedMinted(id: UInt64, name: String, ipfsLink: String, type: UInt64)
10
11 access(all) let CollectionStoragePath: StoragePath
12 access(all) let CollectionPublicPath: PublicPath
13 access(all) let MinterPublishedPath: StoragePath
14
15 access(all) var totalSupply: UInt64
16 access(all) var libraryPassTotalSupply: UInt64
17 access(all) var willoTotalSupply: UInt64
18
19 access(all) resource NFT: NonFungibleToken.NFT {
20 access(all) let serialId: UInt64
21 access(all) let id: UInt64
22 access(all) let name: String
23 access(all) let ipfsLink: String
24 access(all) let type: UInt64
25
26 init(serialId: UInt64, initID: UInt64, name: String, ipfsLink: String, type: UInt64) {
27 self.serialId = serialId
28 self.id = initID
29 self.name = name
30 self.ipfsLink = ipfsLink
31 self.type= type
32 }
33
34 /// createEmptyCollection creates an empty Collection
35 /// and returns it to the caller so that they can own NFTs
36 /// @{NonFungibleToken.Collection}
37 access(all) fun createEmptyCollection(): @{NonFungibleToken.Collection} {
38 return <-Boast.createEmptyCollection(nftType: Type<@Boast.NFT>())
39 }
40
41 access(all) view fun getViews(): [Type] {
42 return [
43 Type<MetadataViews.Display>(),
44 Type<MetadataViews.Royalties>(),
45 Type<MetadataViews.ExternalURL>(),
46 Type<MetadataViews.NFTCollectionData>(),
47 Type<MetadataViews.NFTCollectionDisplay>(),
48 Type<MetadataViews.Serial>(),
49 Type<MetadataViews.EVMBridgedMetadata>()
50 ]
51 }
52
53 access(all) fun resolveView(_ view: Type): AnyStruct? {
54 let url = "https://ipfs.io/ipfs/".concat(self.ipfsLink)
55 switch view {
56 case Type<MetadataViews.Display>():
57 return MetadataViews.Display(
58 name: self.name,
59 description: "With a mission to recall the days of glamour, Mancave Playbabes brings the perfect lifestyle to your fingertips. Combining the charm of the man's world and the alluring pleasures of entertainment, Mancave Playbabes has a unique approach to refuge, here you will find all your advice, and style. \n Registration group element - USA \n Registrant element - Published NFT \n Publication element - ISSUE #6 \n",
60 thumbnail: MetadataViews.IPFSFile(
61 cid: self.ipfsLink,
62 path: nil
63 )
64 )
65 case Type<MetadataViews.Royalties>():
66 var royalties: [MetadataViews.Royalty] = []
67 return MetadataViews.Royalties(royalties)
68 case Type<MetadataViews.Serial>():
69 return MetadataViews.Serial(
70 self.serialId
71 )
72 case Type<MetadataViews.ExternalURL>():
73 return MetadataViews.ExternalURL(url)
74
75 case Type<MetadataViews.NFTCollectionData>():
76 return Boast.resolveContractView(resourceType: Type<@Boast.NFT>(), viewType: Type<MetadataViews.NFTCollectionData>())
77
78 case Type<MetadataViews.NFTCollectionDisplay>():
79 return Boast.resolveContractView(resourceType: Type<@Boast.NFT>(), viewType: Type<MetadataViews.NFTCollectionDisplay>())
80
81 case Type<MetadataViews.EVMBridgedMetadata>():
82 // Implementing this view gives the project control over how the bridged NFT is represented as an
83 // ERC721 when bridged to EVM on Flow via the public infrastructure bridge.
84
85 // Get the contract-level name and symbol values
86 let contractLevel = Boast.resolveContractView(
87 resourceType: nil,
88 viewType: Type<MetadataViews.EVMBridgedMetadata>()
89 ) as! MetadataViews.EVMBridgedMetadata?
90 ?? panic("Could not resolve contract-level EVMBridgedMetadata")
91 // Compose the token-level URI based on a base URI and the token ID, pointing to a JSON file. This
92 // would be a file you've uploaded and are hosting somewhere - in this case HTTP, but this could be
93 // IPFS, S3, a data URL containing the JSON directly, etc.
94 let baseURI = "https://ipfs.io/ipfs/".concat(self.ipfsLink)
95 let uriValue = self.id.toString().concat(".json")
96
97 return MetadataViews.EVMBridgedMetadata(
98 name: contractLevel.name,
99 symbol: contractLevel.symbol,
100 uri: MetadataViews.URI(
101 baseURI: baseURI, // defining baseURI results in a concatenation of baseURI and value
102 value: self.id.toString().concat(".json")
103 )
104 )
105 }
106 return nil
107 }
108 }
109
110 access(all) resource interface BoastCollectionPublic {}
111
112 access(all) resource Collection: NonFungibleToken.Collection, BoastCollectionPublic {
113 access(all) var ownedNFTs: @{UInt64: {NonFungibleToken.NFT}}
114
115 init () {
116 self.ownedNFTs <- {}
117 }
118
119 /// getSupportedNFTTypes returns a list of NFT types that this receiver accepts
120 access(all) view fun getSupportedNFTTypes(): {Type: Bool} {
121 let supportedTypes: {Type: Bool} = {}
122 supportedTypes[Type<@Boast.NFT>()] = true
123 return supportedTypes
124 }
125
126 /// Returns whether or not the given type is accepted by the collection
127 /// A collection that can accept any type should just return true by default
128 access(all) view fun isSupportedNFTType(type: Type): Bool {
129 return type == Type<@Boast.NFT>()
130 }
131
132 access(NonFungibleToken.Withdraw) fun withdraw(withdrawID: UInt64): @{NonFungibleToken.NFT} {
133 let token <- self.ownedNFTs.remove(key: withdrawID) ?? panic("missing NFT")
134
135 emit Withdraw(id: token.id, from: self.owner?.address)
136
137 return <-token
138 }
139
140 access(all) fun deposit(token: @{NonFungibleToken.NFT}) {
141 let token <- token as! @Boast.NFT
142
143 let id: UInt64 = token.id
144
145 let oldToken <- self.ownedNFTs[id] <- token
146
147 emit Deposit(id: id, to: self.owner?.address)
148
149 destroy oldToken
150 }
151
152 access(all) view fun getIDs(): [UInt64] {
153 return self.ownedNFTs.keys
154 }
155
156 /// Gets the amount of NFTs stored in the collection
157 access(all) view fun getLength(): Int {
158 return self.ownedNFTs.length
159 }
160
161 access(all) view fun borrowNFT(_ id: UInt64): &{NonFungibleToken.NFT}? {
162 return (&self.ownedNFTs[id] as &{NonFungibleToken.NFT}?)
163 }
164
165 access(all) view fun borrowBoast(id: UInt64): &Boast.NFT? {
166 if self.ownedNFTs[id] != nil {
167 let ref = (&self.ownedNFTs[id] as &{NonFungibleToken.NFT}?)!
168 return ref as! &Boast.NFT
169 } else {
170 return nil
171 }
172 }
173
174 access(all) view fun borrowViewResolver(id: UInt64): &{ViewResolver.Resolver}? {
175 let nft = (&self.ownedNFTs[id] as &{NonFungibleToken.NFT}?)!
176 let publishedNFT = nft as! &Boast.NFT
177 return publishedNFT as &{ViewResolver.Resolver}
178 }
179
180 /// createEmptyCollection creates an empty Collection of the same type
181 /// and returns it to the caller
182 /// @return A an empty collection of the same type
183 access(all) fun createEmptyCollection(): @{NonFungibleToken.Collection} {
184 return <-Boast.createEmptyCollection(nftType: Type<@Boast.NFT>())
185 }
186 }
187
188 access(all) fun createEmptyCollection(nftType: Type): @{NonFungibleToken.Collection} {
189 return <- create Collection()
190 }
191
192 /// Function that returns all the Metadata Views implemented by a Non Fungible Token
193 ///
194 /// @return An array of Types defining the implemented views. This value will be used by
195 /// developers to know which parameter to pass to the resolveView() method.
196 ///
197 access(all) view fun getContractViews(resourceType: Type?): [Type] {
198 return [
199 Type<MetadataViews.NFTCollectionData>(),
200 Type<MetadataViews.NFTCollectionDisplay>(),
201 Type<MetadataViews.EVMBridgedMetadata>()
202 ]
203 }
204
205 /// Function that resolves a metadata view for this contract.
206 ///
207 /// @param view: The Type of the desired view.
208 /// @return A structure representing the requested view.
209 ///
210 access(all) fun resolveContractView(resourceType: Type?, viewType: Type): AnyStruct? {
211 switch viewType {
212 case Type<MetadataViews.NFTCollectionData>():
213 let collectionData = MetadataViews.NFTCollectionData(
214 storagePath: Boast.CollectionStoragePath,
215 publicPath: Boast.CollectionPublicPath,
216 publicCollection: Type<&Boast.Collection>(),
217 publicLinkedType: Type<&Boast.Collection>(),
218 createEmptyCollectionFunction: (fun(): @{NonFungibleToken.Collection} {
219 return <-Boast.createEmptyCollection(nftType: Type<@Boast.NFT>())
220 })
221 )
222 return collectionData
223 case Type<MetadataViews.NFTCollectionDisplay>():
224 let media = MetadataViews.Media(
225 file: MetadataViews.HTTPFile(
226 url: "https://publishednft.io/logo-desktop.png"
227 ),
228 mediaType: "image/png"
229 )
230 return MetadataViews.NFTCollectionDisplay(
231 name: "The Published NFT Collection",
232 description: "Published NFT is a blockchain eBook publishing platform built on the Flow blockchain, where authors can publish eBooks, Lyrics, Comics, Magazines, Articles, Poems, Recipes, Movie Scripts, Computer Language, etc.",
233 externalURL: MetadataViews.ExternalURL("https://publishednft.io/"),
234 squareImage: media,
235 bannerImage: media,
236 socials: {
237 "twitter": MetadataViews.ExternalURL("https://twitter.com/publishednft/"),
238 "discord": MetadataViews.ExternalURL("https://discord.gg/ct5RPudqpG"),
239 "instagram": MetadataViews.ExternalURL("https://www.instagram.com/publishednft/"),
240 "telegram": MetadataViews.ExternalURL("https://t.me/published_nft"),
241 "reddit": MetadataViews.ExternalURL("https://www.reddit.com/user/PublishedNFT")
242 }
243 )
244 case Type<MetadataViews.EVMBridgedMetadata>():
245 // Implementing this view gives the project control over how the bridged NFT is represented as an ERC721
246 // when bridged to EVM on Flow via the public infrastructure bridge.
247
248 // Compose the contract-level URI. In this case, the contract metadata is located on some HTTP host,
249 // but it could be IPFS, S3, a data URL containing the JSON directly, etc.
250 return MetadataViews.EVMBridgedMetadata(
251 name: "Boast",
252 symbol: "BOAST",
253 uri: MetadataViews.URI(
254 baseURI: nil, // setting baseURI as nil sets the given value as the uri field value
255 value: "https://example-nft.onflow.org/contract-metadata.json"
256 )
257 )
258 }
259 return nil
260 }
261
262 access(all) resource PublishedMinter{
263 access(all) fun mintLibraryPass(_name: String, _ipfsLink: String): @Boast.NFT?{
264
265 if Boast.libraryPassTotalSupply == 9999 {return nil}
266
267 let libraryPassNft <- create Boast.NFT(
268 serialId: Boast.libraryPassTotalSupply,
269 initID: Boast.totalSupply,
270 name: _name,
271 ipfsLink: _ipfsLink,
272 type: 1
273 )
274
275 emit PublishedMinted(id: Boast.totalSupply, name: _name, ipfsLink: _ipfsLink, type: 1)
276
277 Boast.totalSupply = Boast.totalSupply + (1 as UInt64)
278 Boast.libraryPassTotalSupply = Boast.libraryPassTotalSupply + (1 as UInt64)
279
280 return <- libraryPassNft
281 }
282
283 access(all) fun mintWillo(_name: String, _ipfsLink: String): @Boast.NFT?{
284
285 if Boast.willoTotalSupply == 100 {return nil}
286
287 let willoNft <- create Boast.NFT(
288 serialId: Boast.willoTotalSupply,
289 initID: Boast.totalSupply,
290 name: _name,
291 ipfsLink: _ipfsLink,
292 type: 1
293 )
294
295 emit PublishedMinted(id: Boast.totalSupply, name: _name, ipfsLink: _ipfsLink, type: 2)
296
297 Boast.totalSupply = Boast.totalSupply + (1 as UInt64)
298 Boast.willoTotalSupply = Boast.willoTotalSupply + (1 as UInt64)
299
300 return <- willoNft
301 }
302 }
303
304 access(all)
305 fun initMinter() {
306 if self.account.storage.type(at: self.MinterPublishedPath) == nil {
307 self.account.storage.save(<-create PublishedMinter(), to: self.MinterPublishedPath)
308 }
309 }
310
311 init() {
312 self.CollectionStoragePath = /storage/boastCollection
313 self.CollectionPublicPath = /public/boastCollection
314 self.MinterPublishedPath = /storage/minterBoastPath
315
316 self.totalSupply = 0
317 self.libraryPassTotalSupply = 0
318 self.willoTotalSupply = 0
319
320 self.account.storage.save(<- create PublishedMinter(), to: self.MinterPublishedPath)
321
322 // Create a Collection resource and save it to storage
323 let collection <- create Collection()
324 self.account.storage.save(<-collection, to: self.CollectionStoragePath)
325
326 // create a public capability for the collection
327 let collectionCap = self.account.capabilities.storage.issue<&Boast.Collection>(self.CollectionStoragePath)
328 self.account.capabilities.publish(collectionCap, at: self.CollectionPublicPath)
329
330 emit ContractInitialized()
331 }
332}