Smart Contract
MatrixMarket
A.2162bbe13ade251e.MatrixMarket
1import NonFungibleToken from 0x1d7e57aa55817448
2import MetadataViews from 0x1d7e57aa55817448
3
4// MatrixMarket token contract
5pub contract MatrixMarket : NonFungibleToken {
6
7 pub var totalSupply: UInt64
8
9 pub let CollectionStoragePath: StoragePath
10 pub let CollectionPublicPath: PublicPath
11 pub let MinterStoragePath: StoragePath
12 pub let MinterPublicPath: PublicPath
13 //pub var CollectionPrivatePath: PrivatePath
14 pub event ContractInitialized()
15 pub event Withdraw(id: UInt64, from: Address?)
16 pub event Deposit(id: UInt64, to: Address?)
17 pub event Mint(id: UInt64, creator: Address, metadata: {String:String})
18 pub event Destroy(id: UInt64)
19
20 // We use dict to store raw metadata
21 pub resource interface RawMetadata {
22 pub fun getRawMetadata(): {String: String}
23 }
24
25 pub resource NFT: NonFungibleToken.INFT, MetadataViews.Resolver, RawMetadata {
26 pub let id: UInt64
27 pub let creator: Address
28 pub let subCollectionId: String
29 access(self) let metadata: {String:String}
30
31 init(
32 id: UInt64,
33 creator: Address,
34 subCollectionId: String,
35 metadata: {String: String}
36 ) {
37 self.id = id
38 self.creator = creator
39 self.subCollectionId = subCollectionId
40 self.metadata = metadata
41 }
42
43 pub fun getViews(): [Type] {
44 return [
45 Type<MetadataViews.Display>()
46 ]
47 }
48
49 pub fun resolveView(_ view: Type): AnyStruct? {
50 switch view {
51 case Type<MetadataViews.Display>():
52 return MetadataViews.Display(
53 name: self.metadata["name"]!,
54 description: self.metadata["description"]!,
55 thumbnail: MetadataViews.HTTPFile(
56 url: self.metadata["thumbnail"]!
57 )
58 )
59 }
60
61 return nil
62 }
63
64 pub fun getRawMetadata(): {String: String} {
65 return self.metadata
66 }
67
68 destroy() {
69 emit Destroy(id: self.id)
70 }
71 }
72
73 pub resource interface MatrixMarketCollectionPublic {
74 pub fun deposit(token: @NonFungibleToken.NFT)
75 pub fun getIDs(): [UInt64]
76 pub fun borrowNFT(id: UInt64): &NonFungibleToken.NFT
77 pub fun borrowMatrixMarket(id: UInt64): &MatrixMarket.NFT? {
78 post {
79 (result == nil) || (result?.id == id):
80 "Cannot borrow NFT reference: the ID of the returned reference is incorrect"
81 }
82 }
83 }
84
85 pub resource Collection: MatrixMarketCollectionPublic, NonFungibleToken.Provider, NonFungibleToken.Receiver, NonFungibleToken.CollectionPublic, MetadataViews.ResolverCollection {
86 // dictionary of NFT conforming tokens
87 // NFT is a resource type with an `UInt64` ID field
88 pub var ownedNFTs: @{UInt64: NonFungibleToken.NFT}
89
90 init () {
91 self.ownedNFTs <- {}
92 }
93
94 // withdraw removes an NFT from the collection and moves it to the caller
95 pub fun withdraw(withdrawID: UInt64): @NonFungibleToken.NFT {
96 let token <- self.ownedNFTs.remove(key: withdrawID) ?? panic("missing NFT")
97
98 emit Withdraw(id: token.id, from: self.owner?.address)
99
100 return <-token
101 }
102
103 // deposit takes a NFT and adds it to the collections dictionary
104 // and adds the ID to the id array
105 pub fun deposit(token: @NonFungibleToken.NFT) {
106 let token <- token as! @MatrixMarket.NFT
107
108 let id: UInt64 = token.id
109
110 // add the new token to the dictionary which removes the old one
111 let oldToken <- self.ownedNFTs[id] <- token
112
113 emit Deposit(id: id, to: self.owner?.address)
114
115 destroy oldToken
116 }
117
118 // getIDs returns an array of the IDs that are in the collection
119 pub fun getIDs(): [UInt64] {
120 return self.ownedNFTs.keys
121 }
122
123 // borrowNFT gets a reference to an NFT in the collection
124 // so that the caller can read its metadata and call its methods
125 pub fun borrowNFT(id: UInt64): &NonFungibleToken.NFT {
126 return (&self.ownedNFTs[id] as &NonFungibleToken.NFT?)!
127 }
128
129 pub fun borrowMatrixMarket(id: UInt64): &MatrixMarket.NFT? {
130 if self.ownedNFTs[id] != nil {
131 // Create an authorized reference to allow downcasting
132 let ref = &self.ownedNFTs[id] as auth &NonFungibleToken.NFT?
133 return ref as! &MatrixMarket.NFT?
134 }
135
136 return nil
137 }
138
139 pub fun borrowViewResolver(id: UInt64): &AnyResource{MetadataViews.Resolver} {
140 let nft = (&self.ownedNFTs[id] as auth &NonFungibleToken.NFT?)!
141 let mlNFT = nft as! &MatrixMarket.NFT
142 return mlNFT
143 }
144
145 destroy() {
146 destroy self.ownedNFTs
147 }
148 }
149
150 // public function that anyone can call to create a new empty collection
151 pub fun createEmptyCollection(): @NonFungibleToken.Collection {
152 return <- create Collection()
153 }
154
155 // createNewMinter
156 // This allows everyone to mint and
157 // the owner will be creator of the nft
158 pub fun createNewMinter(): @NFTMinter {
159 return <- create NFTMinter()
160 }
161 // Resource that an admin or something similar would own to be
162 // able to mint new NFTs
163 //
164 pub resource NFTMinter {
165
166 // mintNFT mints a new NFT with a new ID
167 // and deposit it in the recipients collection using their collection reference
168 pub fun mintNFT(
169 recipient: &{NonFungibleToken.CollectionPublic},
170 subCollectionId: String,
171 metadata: {String: String}
172 ): &NonFungibleToken.NFT {
173 let creator = self.owner!.address
174 // create a new NFT
175 var newNFT <- create NFT(
176 id: MatrixMarket.totalSupply,
177 creator: creator,
178 subCollectionId: subCollectionId,
179 metadata: metadata
180 )
181
182
183 let tokenRef = &newNFT as &NonFungibleToken.NFT
184 // deposit it in the recipient's account using their reference
185 recipient.deposit(token: <-newNFT)
186
187 MatrixMarket.totalSupply = MatrixMarket.totalSupply + 1
188
189 emit Mint(id: tokenRef.id, creator: creator, metadata: metadata)
190
191 return tokenRef
192 }
193 }
194
195 init() {
196 // Initialize the total supply
197 self.totalSupply = 0
198
199 // Set the named paths
200 self.CollectionStoragePath = /storage/MatrixMarketCollection
201 self.CollectionPublicPath = /public/MatrixMarketCollection
202 self.MinterStoragePath = /storage/MatrixMarketMinter
203 self.MinterPublicPath = /public/MatrixMarketMinter
204
205 // Create a Collection resource and save it to storage
206 let collection <- create Collection()
207 self.account.save(<-collection, to: self.CollectionStoragePath)
208
209 // create a public capability for the collection
210 self.account.link<&MatrixMarket.Collection{NonFungibleToken.Receiver, NonFungibleToken.Provider, NonFungibleToken.CollectionPublic, MatrixMarket.MatrixMarketCollectionPublic}>(
211 self.CollectionPublicPath,
212 target: self.CollectionStoragePath
213 )
214
215 // Create a Minter resource and save it to storage
216 let minter <- create NFTMinter()
217 self.account.save(<-minter, to: self.MinterStoragePath)
218
219 emit ContractInitialized()
220 }
221}
222