Smart Contract
MosaicCreatorV1
A.dbf7a2a1821c9ffa.MosaicCreatorV1
1import FungibleToken from 0xf233dcee88fe0abe
2import NonFungibleToken from 0x1d7e57aa55817448
3
4pub contract MosaicCreatorV1: NonFungibleToken {
5 pub event ContractInitialized()
6 pub event TileAddedToMosaic(mosaicID: UInt32, nftID: UInt64)
7 pub event MosaicCreated(mosaicID: UInt32)
8 pub event Withdraw(id: UInt64, from: Address?)
9 pub event Deposit(id: UInt64, to: Address?)
10 pub event MomentDestroyed(id: UInt64)
11
12 access(self) var mosaics: @{UInt32: Mosaic}
13 pub var mosaicNFTMapping: {UInt32: [UInt64]}
14 pub var nextMosaicID: UInt32
15 pub var totalSupply: UInt64
16 pub var nftToDescription: {UInt64: String}
17 pub var nftToData: {UInt64: NFTData}
18
19 pub struct MosaicData {
20 pub let mosaicID: UInt32
21 pub let collection: String
22 pub let size: UInt64
23 pub let locked: Bool
24
25 init(mosaicID: UInt32, collection: String, size: UInt64, locked: Bool) {
26 self.mosaicID = mosaicID
27 self.collection = collection
28 self.size = size
29 self.locked = locked
30 }
31 }
32
33 pub resource Mosaic {
34 pub let mosaicID: UInt32
35 pub let collection: String
36 pub let size: UInt64
37 pub var locked: Bool
38
39 init(collection: String, size: UInt64) {
40 self.mosaicID = MosaicCreatorV1.nextMosaicID
41 MosaicCreatorV1.nextMosaicID = MosaicCreatorV1.nextMosaicID + 1
42 self.collection = collection
43 self.size = size
44 self.locked = false
45 }
46
47 pub fun lock() {
48 self.locked = true
49 }
50
51 pub fun getDetails(): {String: AnyStruct} {
52 return {
53 "mosaicID": self.mosaicID,
54 "collection": self.collection,
55 "size": self.size,
56 "locked": self.locked,
57 "nftIDs": MosaicCreatorV1.mosaicNFTMapping[self.mosaicID]!
58 }
59 }
60 }
61
62 pub struct NFTData {
63 pub let description: String
64 pub let ownerAddress: Address
65 pub let collectionPath: String
66 pub let collectionCapabilityPath: String
67
68 init(description: String, ownerAddress: Address, collectionPath: String, collectionCapabilityPath: String) {
69 self.description = description
70 self.ownerAddress = ownerAddress
71 self.collectionPath = collectionPath
72 self.collectionCapabilityPath = collectionCapabilityPath
73 }
74 }
75
76 pub resource NFT: NonFungibleToken.INFT {
77 pub let id: UInt64
78 pub var description: String
79 pub var ownerAddress: Address
80 pub var collectionPath: String
81 pub var collectionCapabilityPath: String
82
83 init(description: String, ownerAddress: Address, collectionPath: String, collectionCapabilityPath: String) {
84 self.id = MosaicCreatorV1.totalSupply
85 MosaicCreatorV1.totalSupply = MosaicCreatorV1.totalSupply + 1
86 self.description = description
87 self.ownerAddress = ownerAddress
88 self.collectionPath = collectionPath
89 self.collectionCapabilityPath = collectionCapabilityPath
90 MosaicCreatorV1.nftToDescription[self.id] = description
91 MosaicCreatorV1.nftToData[self.id] = NFTData(description: description, ownerAddress: ownerAddress, collectionPath: collectionPath, collectionCapabilityPath: collectionCapabilityPath)
92 }
93
94 pub fun updateDescription(newDescription: String) {
95 self.description = newDescription
96 MosaicCreatorV1.nftToDescription[self.id] = newDescription
97 let nftData = MosaicCreatorV1.nftToData[self.id]!
98 MosaicCreatorV1.nftToData[self.id] = NFTData(description: newDescription, ownerAddress: nftData.ownerAddress, collectionPath: nftData.collectionPath, collectionCapabilityPath: nftData.collectionCapabilityPath)
99 }
100
101 pub fun updateMetadata(newOwnerAddress: Address, newCollectionPath: String, newCollectionCapabilityPath: String) {
102 self.ownerAddress = newOwnerAddress
103 self.collectionPath = newCollectionPath
104 self.collectionCapabilityPath = newCollectionCapabilityPath
105 let nftData = MosaicCreatorV1.nftToData[self.id]!
106 MosaicCreatorV1.nftToData[self.id] = NFTData(description: nftData.description, ownerAddress: newOwnerAddress, collectionPath: newCollectionPath, collectionCapabilityPath: newCollectionCapabilityPath)
107 }
108
109 destroy() {
110 emit MomentDestroyed(id: self.id)
111 }
112 }
113
114 pub resource Admin {
115 pub fun createMosaic(collection: String, size: UInt64): UInt32 {
116 var newMosaic <- create Mosaic(collection: collection, size: size)
117 let newID = newMosaic.mosaicID
118 MosaicCreatorV1.mosaics[newID] <-! newMosaic
119 MosaicCreatorV1.mosaicNFTMapping[newID] = []
120 emit MosaicCreated(mosaicID: newID)
121 return newID
122 }
123
124 pub fun addTile(mosaicID: UInt32, nftID: UInt64) {
125 // Append the NFT ID to the mosaic's list of NFTs
126 MosaicCreatorV1.mosaicNFTMapping[mosaicID]?.append(nftID)
127 ?? panic("Mosaic with the specified ID does not exist")
128 emit TileAddedToMosaic(mosaicID: mosaicID, nftID: nftID)
129 }
130
131 pub fun borrowMosaic(mosaicID: UInt32): &Mosaic {
132 return (&MosaicCreatorV1.mosaics[mosaicID] as &Mosaic?)!
133 }
134
135 pub fun getMosaicNFTMapping(mosaicID: UInt32): [UInt64]? {
136 return MosaicCreatorV1.mosaicNFTMapping[mosaicID]
137 }
138
139 pub fun mintNFT(description: String, recipient: &{MosaicCreatorV1.MosaicCollectionPublic}, ownerAddress: Address, collectionPath: String, collectionCapabilityPath: String) {
140 let newNFT <- create MosaicCreatorV1.NFT(description: description, ownerAddress: ownerAddress, collectionPath: collectionPath, collectionCapabilityPath: collectionCapabilityPath)
141 recipient.deposit(token: <-newNFT)
142 }
143 }
144
145 pub resource interface MosaicCollectionPublic {
146 pub fun deposit(token: @NonFungibleToken.NFT)
147 pub fun getIDs(): [UInt64]
148 pub fun borrowNFT(id: UInt64): &NonFungibleToken.NFT?
149 pub fun borrowTile(id: UInt64): &MosaicCreatorV1.NFT? {
150 // If the result isn't nil, the id of the returned reference
151 // should be the same as the argument to the function
152 post {
153 (result == nil) || (result?.id == id):
154 "Cannot borrow Mosaic reference: The ID of the returned reference is incorrect"
155 }
156 }
157 }
158
159 pub resource Collection: MosaicCollectionPublic, NonFungibleToken.Provider, NonFungibleToken.Receiver, NonFungibleToken.CollectionPublic {
160 pub var ownedNFTs: @{UInt64: NonFungibleToken.NFT}
161
162 init() {
163 self.ownedNFTs <- {}
164 }
165
166 pub fun withdraw(withdrawID: UInt64): @NonFungibleToken.NFT {
167 let nft <- self.ownedNFTs.remove(key: withdrawID)
168 ?? panic("Cannot withdraw: NFT does not exist in the collection")
169 emit Withdraw(id: withdrawID, from: self.owner?.address)
170 return <-nft
171 }
172
173 pub fun deposit(token: @NonFungibleToken.NFT) {
174 let id = token.id
175 let oldToken <- self.ownedNFTs[id] <- token
176 if self.owner?.address != nil {
177 emit Deposit(id: id, to: self.owner?.address)
178 }
179 destroy oldToken
180 }
181
182 pub fun getIDs(): [UInt64] {
183 return self.ownedNFTs.keys
184 }
185
186 pub fun borrowNFT(id: UInt64): &NonFungibleToken.NFT {
187 return (&self.ownedNFTs[id] as &NonFungibleToken.NFT?)!
188 }
189
190 pub fun borrowNFTSafe(id: UInt64): &NonFungibleToken.NFT? {
191 if let nftRef = &self.ownedNFTs[id] as &NonFungibleToken.NFT? {
192 return nftRef
193 }
194 return nil
195 }
196
197 pub fun borrowTile(id: UInt64): &MosaicCreatorV1.NFT? {
198 if let ref = &self.ownedNFTs[id] as auth &NonFungibleToken.NFT? {
199 return ref as! &MosaicCreatorV1.NFT
200 } else {
201 return nil
202 }
203 }
204
205 pub fun destroyMoments(ids: [UInt64]) {
206 for id in ids {
207 let token <- self.ownedNFTs.remove(key: id)
208 ?? panic("Cannot destroy: NFT does not exist in collection: ".concat(id.toString()))
209 emit Withdraw(id: id, from: self.owner?.address)
210 destroy token
211 }
212 }
213
214 destroy() {
215 destroy self.ownedNFTs
216 }
217 }
218
219 pub fun createEmptyCollection(): @NonFungibleToken.Collection {
220 return <-create MosaicCreatorV1.Collection()
221 }
222
223 pub fun borrowMosaicPublic(mosaicID: UInt32): &Mosaic? {
224 return &self.mosaics[mosaicID] as &Mosaic?
225 }
226
227 pub fun getMosaicDetails(mosaicID: UInt32): {String: AnyStruct} {
228 let mosaicRef = self.borrowMosaicPublic(mosaicID: mosaicID)
229 ?? panic("Mosaic with the specified ID does not exist")
230
231 return mosaicRef.getDetails()
232 }
233
234 init() {
235 self.mosaics <- {}
236 self.mosaicNFTMapping = {}
237 self.nextMosaicID = 0
238 self.totalSupply = 0
239 self.nftToDescription = {}
240 self.nftToData = {}
241
242 self.account.save<@Collection>(<- create Collection(), to: /storage/MosaicCollectionV1)
243 self.account.link<&{MosaicCollectionPublic}>(/public/MosaicCollectionV1, target: /storage/MosaicCollectionV1)
244 self.account.save<@Admin>(<- create Admin(), to: /storage/MosaicAdminV1)
245
246 emit ContractInitialized()
247 }
248}
249