Smart Contract
DimensionXPromo
A.e3ad6030cbaff1c2.DimensionXPromo
1// This is an example implementation of a Flow Non-Fungible Token
2// It is not part of the official standard but it assumed to be
3// very similar to how many NFTs would implement the core functionality.
4
5import FlowToken from 0x1654653399040a61
6import NonFungibleToken from 0x1d7e57aa55817448
7import FungibleToken from 0xf233dcee88fe0abe
8import MetadataViews from 0x1d7e57aa55817448
9
10pub contract DimensionXPromo: NonFungibleToken {
11
12 pub var totalSupply: UInt64
13 access(self) var metadataUrl: String
14
15 pub event ContractInitialized()
16 pub event Withdraw(id: UInt64, from: Address?)
17 pub event Deposit(id: UInt64, to: Address?)
18
19 pub let CollectionStoragePath: StoragePath
20 pub let CollectionPublicPath: PublicPath
21 pub let MinterStoragePath: StoragePath
22
23 pub resource NFT: NonFungibleToken.INFT, MetadataViews.Resolver {
24 pub let id: UInt64
25
26 init(
27 id: UInt64,
28 ) {
29 self.id = id
30 }
31
32 pub fun getViews(): [Type] {
33 return [
34 Type<MetadataViews.ExternalURL>(),
35 Type<MetadataViews.Display>(),
36 Type<MetadataViews.Royalties>(),
37 Type<MetadataViews.NFTCollectionData>(),
38 Type<MetadataViews.NFTCollectionDisplay>()
39 ]
40 }
41
42 pub fun resolveView(_ view: Type): AnyStruct? {
43 switch view {
44 case Type<MetadataViews.ExternalURL>():
45 return MetadataViews.ExternalURL(
46 url: DimensionXPromo.metadataUrl.concat(self.id.toString())
47 )
48 case Type<MetadataViews.Display>():
49 return MetadataViews.Display(
50 name: ("DimensionX #").concat(self.id.toString()),
51 description: "A Promotional NFT for the DimensionX Game!",
52 thumbnail: MetadataViews.HTTPFile(
53 url: "https://dimensionxstorage.blob.core.windows.net/dmxgamepromos/dmx_placeholder_promo_image.png"
54 )
55 )
56 case Type<MetadataViews.Royalties>():
57 return [MetadataViews.Royalty(
58 receiver: DimensionXPromo.account.getCapability<&{FungibleToken.Receiver}>(MetadataViews.getRoyaltyReceiverPublicPath()),
59 cut: UFix64(0.10),
60 description: "Crypthulhu royalties",
61 )]
62 case Type<MetadataViews.NFTCollectionData>():
63 return MetadataViews.NFTCollectionData(
64 storagePath: DimensionXPromo.CollectionStoragePath,
65 publicPath: DimensionXPromo.CollectionPublicPath,
66 providerPath: /private/dimensionXPromoCollection,
67 publicCollection: Type<&DimensionXPromo.Collection{DimensionXPromo.DimensionXPromoCollectionPublic}>(),
68 publicLinkedType: Type<&DimensionXPromo.Collection{DimensionXPromo.DimensionXPromoCollectionPublic,NonFungibleToken.CollectionPublic,NonFungibleToken.Receiver,MetadataViews.ResolverCollection}>(),
69 providerLinkedType: Type<&DimensionXPromo.Collection{DimensionXPromo.DimensionXPromoCollectionPublic,NonFungibleToken.CollectionPublic,NonFungibleToken.Provider,MetadataViews.ResolverCollection}>(),
70 createEmptyCollectionFunction: (fun (): @NonFungibleToken.Collection {
71 return <-DimensionXPromo.createEmptyCollection()
72 })
73 )
74 case Type<MetadataViews.NFTCollectionDisplay>():
75 return MetadataViews.NFTCollectionDisplay(
76 name: "Dimension X",
77 description: "Dimension X is a Free-to-Play, Play-to-Earn strategic role playing game on the Flow blockchain set in the Dimension X comic book universe, where a pan-dimensional explosion created super powered humans, aliens and monsters with radical and terrifying superpowers!",
78 externalURL: MetadataViews.ExternalURL("https://dimensionxnft.com"),
79 squareImage: MetadataViews.Media(
80 file: MetadataViews.HTTPFile(url: DimensionXPromo.metadataUrl.concat("collection_image.png")),
81 mediaType: "image/png"
82 ),
83 bannerImage: MetadataViews.Media(
84 file: MetadataViews.HTTPFile(url: DimensionXPromo.metadataUrl.concat("collection_banner.png")),
85 mediaType: "image/png"
86 ),
87 socials: {
88 "discord": MetadataViews.ExternalURL("https://discord.gg/BK5yAD6VQg"),
89 "twitter": MetadataViews.ExternalURL("https://twitter.com/DimensionX_NFT")
90 }
91 )
92 }
93
94 return nil
95 }
96 }
97
98 pub resource interface DimensionXPromoCollectionPublic {
99 pub fun deposit(token: @NonFungibleToken.NFT)
100 pub fun getIDs(): [UInt64]
101 pub fun borrowNFT(id: UInt64): &NonFungibleToken.NFT
102 pub fun borrowDimensionXPromo(id: UInt64): &DimensionXPromo.NFT? {
103 post {
104 (result == nil) || (result?.id == id):
105 "Cannot borrow DimensionXPromo reference: the ID of the returned reference is incorrect"
106 }
107 }
108 }
109
110 pub resource Collection: DimensionXPromoCollectionPublic, NonFungibleToken.Provider, NonFungibleToken.Receiver, NonFungibleToken.CollectionPublic, MetadataViews.ResolverCollection {
111 // dictionary of NFT conforming tokens
112 // NFT is a resource type with an `UInt64` ID field
113 pub var ownedNFTs: @{UInt64: NonFungibleToken.NFT}
114
115 init () {
116 self.ownedNFTs <- {}
117 }
118
119 // withdraw removes an NFT from the collection and moves it to the caller
120 pub fun withdraw(withdrawID: UInt64): @NonFungibleToken.NFT {
121 let token <- self.ownedNFTs.remove(key: withdrawID) ?? panic("missing NFT")
122
123 emit Withdraw(id: token.id, from: self.owner?.address)
124
125 return <-token
126 }
127
128 // deposit takes a NFT and adds it to the collections dictionary
129 // and adds the ID to the id array
130 pub fun deposit(token: @NonFungibleToken.NFT) {
131 let token <- token as! @DimensionXPromo.NFT
132
133 let id: UInt64 = token.id
134
135 // add the new token to the dictionary which removes the old one
136 let oldToken <- self.ownedNFTs[id] <- token
137
138 emit Deposit(id: id, to: self.owner?.address)
139
140 destroy oldToken
141 }
142
143 // getIDs returns an array of the IDs that are in the collection
144 pub fun getIDs(): [UInt64] {
145 return self.ownedNFTs.keys
146 }
147
148 // borrowNFT gets a reference to an NFT in the collection
149 // so that the caller can read its metadata and call its methods
150 pub fun borrowNFT(id: UInt64): &NonFungibleToken.NFT {
151 return (&self.ownedNFTs[id] as &NonFungibleToken.NFT?)!
152 }
153
154 pub fun borrowDimensionXPromo(id: UInt64): &DimensionXPromo.NFT? {
155 if self.ownedNFTs[id] != nil {
156 // Create an authorized reference to allow downcasting
157 let ref = (&self.ownedNFTs[id] as auth &NonFungibleToken.NFT?)!
158 return ref as! &DimensionXPromo.NFT
159 }
160
161 return nil
162 }
163
164 pub fun borrowViewResolver(id: UInt64): &AnyResource{MetadataViews.Resolver} {
165 let nft = (&self.ownedNFTs[id] as auth &NonFungibleToken.NFT?)!
166 let dimensionXPromo = nft as! &DimensionXPromo.NFT
167 return dimensionXPromo as &AnyResource{MetadataViews.Resolver}
168 }
169
170 destroy() {
171 destroy self.ownedNFTs
172 }
173 }
174
175 // public function that anyone can call to create a new empty collection
176 pub fun createEmptyCollection(): @NonFungibleToken.Collection {
177 return <- create Collection()
178 }
179
180 // Resource that an admin or something similar would own to be
181 // able to mint new NFTs
182 //
183 pub resource NFTMinter {
184
185 // mintNFT mints a new NFT with a new ID
186 // and deposit it in the recipients collection using their collection reference
187 pub fun mintNFT(
188 recipient: &Collection{NonFungibleToken.CollectionPublic},
189 ) {
190
191 // create a new NFT
192 var newNFT <- create NFT(
193 id: DimensionXPromo.totalSupply,
194 )
195
196 // deposit it in the recipient's account using their reference
197 recipient.deposit(token: <-newNFT)
198
199 DimensionXPromo.totalSupply = DimensionXPromo.totalSupply + UInt64(1)
200 }
201 }
202
203 init() {
204 // Initialize the total supply
205 self.totalSupply = 0
206 self.metadataUrl = "https://www.dimensionx.com/promo/"
207
208 // Set the named paths
209 self.CollectionStoragePath = /storage/dimensionXPromoCollection
210 self.CollectionPublicPath = /public/dimensionXPromoCollection
211 self.MinterStoragePath = /storage/dimensionXMinter
212
213 // Create a Collection resource and save it to storage
214 let collection <- create Collection()
215 self.account.save(<-collection, to: self.CollectionStoragePath)
216
217 // create a public capability for the collection
218 self.account.link<&DimensionXPromo.Collection{NonFungibleToken.CollectionPublic, DimensionXPromo.DimensionXPromoCollectionPublic}>(
219 self.CollectionPublicPath,
220 target: self.CollectionStoragePath
221 )
222
223 // Create a Minter resource and save it to storage
224 let minter <- create NFTMinter()
225 self.account.save(<-minter, to: self.MinterStoragePath)
226
227 emit ContractInitialized()
228 }
229}
230
231