Smart Contract
Monsoon
A.8234007b36f8113c.Monsoon
1/**
2* SPDX-License-Identifier: UNLICENSED
3*/
4
5import NonFungibleToken from 0x1d7e57aa55817448
6
7// Monsoon
8// NFT items for cards!
9//
10pub contract Monsoon: NonFungibleToken {
11
12 // Events
13 //
14 pub event ContractInitialized()
15 pub event Withdraw(id: UInt64, from: Address?)
16 pub event Destroy(id: UInt64, from: Address?)
17 pub event Deposit(id: UInt64, to: Address?)
18 pub event Minted(id: UInt64, templateID: UInt64, typeOfCard: UInt32, universeID: UInt32, numSeries: UInt32, numSerial: UInt32, CID: String)
19 pub event monsoonCutPercentageChange(newPercent: UFix64)
20 pub event monsoonCutPercentageReceiverChange(newReceiver: Address)
21
22
23
24 // Named Paths
25 //
26 pub let CollectionStoragePath: StoragePath
27 pub let CollectionPublicPath: PublicPath
28 pub let MinterStoragePath: StoragePath
29
30 // totalSupply
31 // The total number of Monsoon that have been minted
32 //
33 pub var totalSupply: UInt64
34
35 // totalSupplyUniverseType
36 // Dictionary with the total number minted desglosed by Universe_Type
37 //
38 access(contract) var totalSupplyUniverseType: {String: UInt64}
39
40 // totalBurned
41 // Total Number of cards burned in order to get fusion cards
42 //
43 pub var totalBurned: UInt64
44
45 // monsoonCutSalesPercentage
46 // Commission in the market of the sales
47 //
48 pub var monsoonCutPercentage: UFix64
49 pub var addressReceivermonsoonCutPercentage: Address
50
51 // function to inform about all totals
52 pub fun getTotals(): {String: UInt64} {
53 var totals: {String: UInt64} = {}
54 var old = totals.insert(key: "totalSupply", self.totalSupply)
55 old = totals.insert(key: "totalBurned", self.totalBurned)
56
57 for key in self.totalSupplyUniverseType.keys {
58
59 old = totals.insert(key: key, self.totalSupplyUniverseType[key] ?? (0 as UInt64))
60 }
61 return totals
62 }
63
64 pub struct CardData {
65 // This is the key of the templateCard
66 pub let templateID: UInt64
67 // 0 Comun 1 Rare 2 Combination 3 Legendarie
68 pub let typeOfCard: UInt32
69 // universe of the card (0 Zombicide 1 .....)
70 pub let universeID: UInt32
71 // printing number (as an book editon)
72 pub let numSeries: UInt32
73 // Number of the serie in the card
74 pub let numSerial: UInt32
75 //File static card in ipfs
76 pub let CID: String
77
78
79 init(templateID: UInt64, typeOfCard: UInt32, universeID: UInt32, numSeries: UInt32, numSerial: UInt32, CID: String) {
80 self.templateID = templateID
81 self.typeOfCard = typeOfCard
82 self.universeID = universeID
83 self.numSeries = numSeries
84 self.numSerial = numSerial
85 self.CID = CID
86 }
87 }
88
89 // NFT
90 // A Monsoon Card as an NFT
91 //
92 pub resource NFT: NonFungibleToken.INFT {
93 // The token's ID
94 pub let id: UInt64
95
96 pub let data: CardData
97
98
99 // initializer
100 //
101 init(initID: UInt64, initTemplateID: UInt64, initTypeOfCard: UInt32, initUniverseID: UInt32, initnumSeries: UInt32, initnumSerial: UInt32, initCID: String) {
102 self.id = initID
103
104 self.data = CardData(templateID: initTemplateID, typeOfCard: initTypeOfCard, universeID: initUniverseID, numSeries: initnumSeries, numSerial: initnumSerial, CID: initCID)
105 emit Minted(id: self.id, templateID: self.data.templateID, typeOfCard: self.data.typeOfCard, universeID: self.data.universeID, numSeries: self.data.numSeries, numSerial: self.data.numSerial, CID: self.data.CID)
106
107 }
108 }
109
110 // This is the interface that users can cast their Monsoon Collection as
111 // to allow others to deposit Monsoon into their Collection. It also allows for reading
112 // the details of Monsoon in the Collection.
113 pub resource interface MonsoonCollectionPublic {
114 pub fun deposit(token: @NonFungibleToken.NFT)
115 pub fun getIDs(): [UInt64]
116
117 //list of the propertied of the cards collections
118 pub fun listCards(): {UInt64: CardData}
119
120 pub fun borrowNFT(id: UInt64): &NonFungibleToken.NFT
121 pub fun borrowMonsoonCard(id: UInt64): &Monsoon.NFT? {
122 // If the result isn't nil, the id of the returned reference
123 // should be the same as the argument to the function
124 post {
125 (result == nil) || (result?.id == id):
126 "Cannot borrow MonsoonCard reference: The ID of the returned reference is incorrect"
127 }
128 }
129 }
130
131 // Collection
132 // A collection of MonsoonCard NFTs owned by an account
133 //
134 pub resource Collection: MonsoonCollectionPublic, NonFungibleToken.Provider, NonFungibleToken.Receiver, NonFungibleToken.CollectionPublic {
135 // dictionary of NFT conforming tokens
136 // NFT is a resource type with an `UInt64` ID field
137 //
138 pub var ownedNFTs: @{UInt64: NonFungibleToken.NFT}
139
140 // withdraw
141 // Removes an NFT from the collection and moves it to the caller
142 //
143 pub fun withdraw(withdrawID: UInt64): @NonFungibleToken.NFT {
144 let token <- self.ownedNFTs.remove(key: withdrawID) ?? panic("missing NFT")
145
146 emit Withdraw(id: token.id, from: self.owner?.address)
147
148 return <-token
149 }
150
151 // deposit
152 // Takes a NFT and adds it to the collections dictionary
153 // and adds the ID to the id array
154 //
155 pub fun deposit(token: @NonFungibleToken.NFT) {
156 let token <- token as! @Monsoon.NFT
157
158 let id: UInt64 = token.id
159
160 // add the new token to the dictionary which removes the old one
161 let oldToken <- self.ownedNFTs[id] <- token
162
163 emit Deposit(id: id, to: self.owner?.address)
164
165 destroy oldToken
166 }
167
168 // getIDs
169 // Returns an array of the IDs that are in the collection
170 //
171 pub fun getIDs(): [UInt64] {
172 return self.ownedNFTs.keys
173 }
174
175 // listCards
176 // functions for list the properties of the user's cards
177 //
178 pub fun listCards(): {UInt64: CardData} {
179 var cardsList: {UInt64:CardData} = {}
180 for key in self.ownedNFTs.keys {
181 //let el = &self.ownedNFTs[key] as &Monsoon.NFT
182 let ref = &self.ownedNFTs[key] as auth &NonFungibleToken.NFT? //update secure cadence
183 let el = ref as! &Monsoon.NFT
184 cardsList.insert(key: el.id, el.data)
185 }
186 return cardsList
187 }
188
189 // borrowNFT
190 // Gets a reference to an NFT in the collection
191 // so that the caller can read its metadata and call its methods
192 //
193 pub fun borrowNFT(id: UInt64): &NonFungibleToken.NFT {
194 return (&self.ownedNFTs[id] as &NonFungibleToken.NFT?)! //update secure cadence
195 }
196
197 // borrowMonsoonCard
198 // Gets a reference to an NFT in the collection as a MonsoonCard,
199 // exposing all of its fields.
200 // This is safe as there are no functions that can be called on the MonsoonCard.
201 //
202 pub fun borrowMonsoonCard(id: UInt64): &Monsoon.NFT? {
203 if self.ownedNFTs[id] != nil {
204 let ref = &self.ownedNFTs[id] as auth &NonFungibleToken.NFT? // update secure cadence
205 return ref as! &Monsoon.NFT
206 } else {
207 return nil
208 }
209 }
210
211 // function for burned the cards in order of allow mint a fusion card
212 pub fun batchDestroy(keys: [UInt64]): Int {
213 var nBurned: Int = 0
214
215 // in a first moment check if all the keys exits in the collection before starting to destroy
216 for key in keys {
217 if self.ownedNFTs[key] == nil {
218 panic("The reference ".concat(key.toString()).concat(" doesn't exits in the account collection"))
219 }
220 }
221
222 for key in keys {
223 let token <- self.ownedNFTs.remove(key: key) ?? panic("missing NFT")
224 emit Destroy(id: token.id, from: self.owner?.address)
225 destroy token
226 Monsoon.totalBurned = Monsoon.totalBurned + (1 as UInt64)
227 nBurned = nBurned +1
228 }
229
230 return nBurned
231 }
232
233
234 // destructor
235 destroy() {
236 destroy self.ownedNFTs
237 }
238
239 // initializer
240 //
241 init () {
242 self.ownedNFTs <- {}
243 }
244 }
245
246 // createEmptyCollection
247 // public function that anyone can call to create a new empty collection
248 //
249 pub fun createEmptyCollection(): @NonFungibleToken.Collection {
250 return <- create Collection()
251 }
252
253 // NFTMinter
254 // Resource that an admin or something similar would own to be
255 // able to mint new NFTs
256 //
257 pub resource NFTMinter {
258
259 // mintNFT
260 // Mints a new NFT with a new ID
261 // and deposit it in the recipients collection using their collection reference
262 //
263 pub fun mintNFT(recipient: &{NonFungibleToken.CollectionPublic}, templateID: UInt64, typeOfCard: UInt32, universeID: UInt32, numSeries: UInt32, numSerial: UInt32, CID: String) {
264 emit Minted(id: Monsoon.totalSupply, templateID: templateID, typeOfCard: typeOfCard, universeID: universeID, numSeries: numSeries, numSerial: numSerial, CID: CID)
265
266 // deposit it in the recipient's account using their reference
267 recipient.deposit(token: <-create Monsoon.NFT(initID: Monsoon.totalSupply, initTemplateID: templateID, initTypeOfCard: typeOfCard, initUniverseID: universeID, initnumSeries: numSeries, initnumSerial: numSerial, initCID: CID))
268
269 Monsoon.totalSupply = Monsoon.totalSupply + (1 as UInt64)
270
271
272 // store the total supply by universe and type of cards
273 let keyUnvTyp: String = universeID.toString().concat("_").concat(typeOfCard.toString())
274 if (!Monsoon.totalSupplyUniverseType.containsKey(keyUnvTyp)) {
275 Monsoon.totalSupplyUniverseType.insert(key: keyUnvTyp, 1)
276 } else {
277 var auxCont = Monsoon.totalSupplyUniverseType[keyUnvTyp] ?? (0 as UInt64)
278 auxCont = auxCont + (1 as UInt64)
279 Monsoon.totalSupplyUniverseType.insert(key: keyUnvTyp, auxCont)
280 }
281 //-------------------------------------------------------
282
283 }
284
285 pub fun changeMonsoonCutPercentage (newCutPercentage: UFix64) {
286 Monsoon.monsoonCutPercentage = newCutPercentage
287 emit monsoonCutPercentageChange(newPercent: Monsoon.monsoonCutPercentage)
288 }
289
290 pub fun changeaddressReceivermonsoonCutPercentage (newReceiver: Address) {
291 Monsoon.addressReceivermonsoonCutPercentage = newReceiver
292 emit monsoonCutPercentageReceiverChange(newReceiver: Monsoon.addressReceivermonsoonCutPercentage)
293 }
294
295
296 }
297
298 // fetch
299 // Get a reference to a MonsoonCard from an account's Collection, if available.
300 // If an account does not have a Monsoon.Collection, panic.
301 // If it has a collection but does not contain the itemID, return nil.
302 // If it has a collection and that collection contains the itemID, return a reference to that.
303 //
304 pub fun fetch(_ from: Address, itemID: UInt64): &Monsoon.NFT? {
305 let collection = getAccount(from)
306 .getCapability(Monsoon.CollectionPublicPath)!
307 .borrow<&Monsoon.Collection{Monsoon.MonsoonCollectionPublic}>()
308 ?? panic("Couldn't get collection")
309 // We trust Monsoon.Collection.borowMonsoonCard to get the correct itemID
310 // (it checks it before returning it).
311 return collection.borrowMonsoonCard(id: itemID)
312 }
313
314 // initializer
315 //
316 init() {
317 // Set our named paths
318 self.CollectionStoragePath = /storage/monsoonDigitalCollection
319 self.CollectionPublicPath = /public/monsoonDigitalCollection
320 self.MinterStoragePath = /storage/monsoonDigitalMinter
321
322 // Initialize the total supply
323 self.totalSupply = 0
324 self.totalSupplyUniverseType = {}
325 self.totalBurned = 0
326
327 self.monsoonCutPercentage = 0.05
328 self.addressReceivermonsoonCutPercentage = self.account.address
329
330
331
332
333 // Create a Minter resource and save it to storage
334 let minter <- create NFTMinter()
335 self.account.save(<-minter, to: self.MinterStoragePath)
336
337 emit ContractInitialized()
338 }
339}
340