Smart Contract
CarClub
A.f887ece39166906e.CarClub
1import NonFungibleToken from 0x1d7e57aa55817448
2import MetadataViews from 0x1d7e57aa55817448
3import ViewResolver from 0x1d7e57aa55817448
4
5access(all) contract CarClub: NonFungibleToken {
6
7 access(all) let CollectionStoragePath: StoragePath
8 access(all) let CollectionPublicPath: PublicPath
9 access(all) let CollectionPrivatePath: PrivatePath
10 access(all) let AdminStoragePath: StoragePath
11
12 access(all) var totalSupply: UInt64
13
14 access(all) struct CarClubMetadata {
15 access(all) let id: UInt64
16 access(all) let name: String
17 access(all) let description: String
18 access(all) let image: String
19 access(all) let traits: {String: String}
20
21 init(id: UInt64 ,name: String, description: String, image: String, traits: {String: String}) {
22 self.id = id
23 self.name=name
24 self.description = description
25 self.image = image
26 self.traits = traits
27 }
28 }
29
30 access(all) resource NFT: NonFungibleToken.NFT {
31 access(all) let id: UInt64
32 access(all) let name: String
33 access(all) let description: String
34 access(all) var image: String
35 access(all) let traits: {String: String}
36
37 init(id: UInt64, name: String, description: String, image: String, traits: {String: String}) {
38 self.id = id
39 self.name=name
40 self.description = description
41 self.image = image
42 self.traits = traits
43 }
44
45 access(all) fun revealThumbnail() {
46 let urlBase = self.image.slice(from: 0, upTo: 47)
47 let newImage = urlBase.concat(self.id.toString()).concat(".png")
48 self.image = newImage
49 }
50
51 access(all) fun createEmptyCollection(): @{NonFungibleToken.Collection} {
52 return <- CarClub.createEmptyCollection(nftType: Type<@NFT>())
53 }
54
55 access(all) view fun getViews(): [Type] {
56 return [
57 Type<MetadataViews.NFTView>(),
58 Type<MetadataViews.Display>(),
59 Type<MetadataViews.ExternalURL>(),
60 Type<MetadataViews.NFTCollectionData>(),
61 Type<MetadataViews.NFTCollectionDisplay>(),
62 Type<CarClub.CarClubMetadata>(),
63 Type<MetadataViews.Royalties>(),
64 Type<MetadataViews.Traits>()
65 ]
66 }
67
68 access(all) fun resolveView(_ view: Type): AnyStruct? {
69 switch view {
70 case Type<MetadataViews.Display>():
71 return MetadataViews.Display(
72 name: self.name,
73 description: self.description,
74 thumbnail: MetadataViews.IPFSFile(
75 cid: self.image,
76 path: nil
77 )
78 )
79 case Type<MetadataViews.ExternalURL>():
80 return MetadataViews.ExternalURL("https://driverz.world")
81 case Type<MetadataViews.NFTCollectionData>():
82 return CarClub.resolveContractView(resourceType: Type<@NFT>(), viewType: Type<MetadataViews.NFTCollectionData>())
83 case Type<MetadataViews.NFTCollectionDisplay>():
84 return CarClub.resolveContractView(resourceType: Type<@NFT>(), viewType: Type<MetadataViews.NFTCollectionDisplay>())
85 case Type<CarClub.CarClubMetadata>():
86 return CarClub.CarClubMetadata(
87 id: self.id,
88 name: self.name,
89 description: self.description,
90 image: self.image,
91 traits: self.traits
92 )
93 case Type<MetadataViews.Royalties>():
94 return MetadataViews.Royalties([])
95 case Type<MetadataViews.Traits>():
96 let traits: [MetadataViews.Trait] = []
97 for trait in self.traits.keys {
98 traits.append(MetadataViews.Trait(
99 name: trait,
100 value: self.traits[trait]!,
101 displayType: nil,
102 rarity: nil
103 ))
104 }
105 return MetadataViews.Traits(traits)
106 }
107 return nil
108 }
109 }
110
111 access(all) resource interface CollectionPublic {
112 access(all) fun deposit(token: @{NonFungibleToken.NFT})
113 access(all) view fun getIDs(): [UInt64]
114 access(all) fun borrowCarClub(id: UInt64): &CarClub.NFT? {
115 // If the result isn't nil, the id of the returned reference
116 // should be the same as the argument to the function
117 post {
118 (result == nil) || (result?.id == id):
119 "Cannot borrow Car Club reference: The ID of the returned reference is incorrect"
120 }
121 }
122 }
123
124 access(all) resource Collection: CollectionPublic, NonFungibleToken.Collection {
125 access(all) var ownedNFTs: @{UInt64: {NonFungibleToken.NFT}}
126
127 access(NonFungibleToken.Withdraw) fun withdraw(withdrawID: UInt64): @{NonFungibleToken.NFT} {
128 let token <- self.ownedNFTs.remove(key: withdrawID) ?? panic("missing NFT")
129 return <-token
130 }
131
132 access(all) fun deposit(token: @{NonFungibleToken.NFT}) {
133 let token <- token as! @CarClub.NFT
134 let id: UInt64 = token.id
135 let oldToken <- self.ownedNFTs[id] <- token
136 destroy oldToken
137 }
138
139 access(all) view fun getSupportedNFTTypes(): {Type: Bool} {
140 let supportedTypes: {Type: Bool} = {}
141 supportedTypes[Type<@NFT>()] = true
142 return supportedTypes
143 }
144
145 access(all) view fun isSupportedNFTType(type: Type): Bool {
146 return type == Type<@NFT>()
147 }
148
149 access(all) view fun getIDs(): [UInt64] {
150 return self.ownedNFTs.keys
151 }
152
153 access(all) view fun borrowViewResolver(id: UInt64): &{ViewResolver.Resolver}? {
154 if let nft = &self.ownedNFTs[id] as &{NonFungibleToken.NFT}? {
155 return nft as &{ViewResolver.Resolver}
156 }
157 return nil
158 }
159
160 access(all) view fun borrowNFT(_ id: UInt64): &{NonFungibleToken.NFT}? {
161 return (&self.ownedNFTs[id] as &{NonFungibleToken.NFT}?)
162 }
163
164 access(all) fun borrowCarClub(id: UInt64): &CarClub.NFT? {
165 if let nft = &self.ownedNFTs[id] as &{NonFungibleToken.NFT}? {
166 return nft as! &NFT
167 }
168 return nil
169 }
170
171 access(all) fun createEmptyCollection(): @{NonFungibleToken.Collection} {
172 return <- CarClub.createEmptyCollection(nftType: Type<@NFT>())
173 }
174
175 init () {
176 self.ownedNFTs <- {}
177 }
178 }
179
180 access(all) fun createEmptyCollection(nftType: Type): @{NonFungibleToken.Collection} {
181 return <- create Collection()
182 }
183
184 access(all) resource Admin {
185 access(all) fun mintNFT(
186 recipient: &{NonFungibleToken.CollectionPublic},
187 name: String,
188 description: String,
189 image: String,
190 traits: {String: String}
191 ) {
192 CarClub.totalSupply = CarClub.totalSupply + 1
193
194 recipient.deposit(token: <- create CarClub.NFT(
195 id: CarClub.totalSupply,
196 name: name,
197 description: description,
198 image:image,
199 traits: traits
200 ))
201 }
202 }
203
204 access(all) view fun getContractViews(resourceType: Type?): [Type] {
205 return [
206 Type<MetadataViews.NFTCollectionData>(),
207 Type<MetadataViews.NFTCollectionDisplay>()
208 ]
209 }
210
211 access(all) fun resolveContractView(resourceType: Type?, viewType: Type): AnyStruct? {
212 switch viewType {
213 case Type<MetadataViews.NFTCollectionData>():
214 let collectionData = MetadataViews.NFTCollectionData(
215 storagePath: self.CollectionStoragePath,
216 publicPath: self.CollectionPublicPath,
217 publicCollection: Type<&Collection>(),
218 publicLinkedType: Type<&Collection>(),
219 createEmptyCollectionFunction: (fun(): @{NonFungibleToken.Collection} {
220 return <- CarClub.createEmptyCollection(nftType: Type<@NFT>())
221 })
222 )
223 return collectionData
224 case Type<MetadataViews.NFTCollectionDisplay>():
225 let squareMedia = MetadataViews.Media(
226 file: MetadataViews.HTTPFile(
227 url: "https://driverz.world/DriverzNFT-logo.png"
228 ),
229 mediaType: "image"
230 )
231 let bannerMedia = MetadataViews.Media(
232 file: MetadataViews.HTTPFile(
233 url: "https://driverz.world/DriverzNFT-logo.png"
234 ),
235 mediaType: "image"
236 )
237 return MetadataViews.NFTCollectionDisplay(
238 name: "Driverz Car Club",
239 description: "Driverz Car Club Collection",
240 externalURL: MetadataViews.ExternalURL("https://driverz.world/"),
241 squareImage: squareMedia,
242 bannerImage: bannerMedia,
243 socials: {
244 "twitter": MetadataViews.ExternalURL("https://twitter.com/DriverzWorld"),
245 "discord": MetadataViews.ExternalURL("https://discord.gg/driverz"),
246 "instagram": MetadataViews.ExternalURL("https://www.instagram.com/driverzworld")
247 }
248 )
249 }
250 return nil
251 }
252
253 init() {
254 self.CollectionStoragePath = /storage/CarClubCollection
255 self.CollectionPublicPath = /public/CarClubCollection
256 self.CollectionPrivatePath = /private/CarClubCollection
257 self.AdminStoragePath = /storage/CarClubMinter
258
259 self.totalSupply = 0
260
261 let minter <- create Admin()
262 self.account.storage.save(<-minter, to: self.AdminStoragePath)
263
264 let collection <- create Collection()
265 self.account.storage.save(<-collection, to: CarClub.CollectionStoragePath)
266 let collectionCap = self.account.capabilities.storage.issue<&Collection>(self.CollectionStoragePath)
267 self.account.capabilities.publish(collectionCap, at: self.CollectionPublicPath)
268 }
269}