Smart Contract
SimpleFlunks
A.bfffec679fff3a94.SimpleFlunks
1import NonFungibleToken from 0x1d7e57aa55817448
2import MetadataViews from 0x1d7e57aa55817448
3import ViewResolver from 0x1d7e57aa55817448
4
5access(all)
6contract SimpleFlunks: NonFungibleToken {
7
8 access(all) event ContractInitialized()
9 access(all) event Withdraw(id: UInt64, from: Address?)
10 access(all) event Deposit(id: UInt64, to: Address?)
11 access(all) event Minted(id: UInt64, to: Address?)
12
13 access(all) var totalSupply: UInt64
14
15 access(all) let CollectionStoragePath: StoragePath
16 access(all) let CollectionPublicPath: PublicPath
17 access(all) let AdminStoragePath: StoragePath
18
19 access(all) resource NFT: NonFungibleToken.NFT, ViewResolver.Resolver {
20
21 access(all) let id: UInt64
22 access(all) let name: String
23 access(all) let description: String
24 access(all) let image: String
25
26 init(id: UInt64, name: String, description: String, image: String) {
27 self.id = id
28 self.name = name
29 self.description = description
30 self.image = image
31 }
32
33 access(all) view fun getViews(): [Type] {
34 return [Type<MetadataViews.Display>()]
35 }
36
37 access(all) fun resolveView(_ view: Type): AnyStruct? {
38 switch view {
39 case Type<MetadataViews.Display>():
40 return MetadataViews.Display(
41 name: self.name,
42 description: self.description,
43 thumbnail: MetadataViews.HTTPFile(url: self.image)
44 )
45 }
46 return nil
47 }
48
49 access(all) fun createEmptyCollection(): @{NonFungibleToken.Collection} {
50 return <-create Collection()
51 }
52 }
53
54 access(all) resource Collection: NonFungibleToken.Provider, NonFungibleToken.Receiver, NonFungibleToken.Collection, NonFungibleToken.CollectionPublic, ViewResolver.ResolverCollection {
55
56 access(all) var ownedNFTs: @{UInt64: {NonFungibleToken.NFT}}
57
58 init() {
59 self.ownedNFTs <- {}
60 }
61
62 access(NonFungibleToken.Withdraw) fun withdraw(withdrawID: UInt64): @{NonFungibleToken.NFT} {
63 let token <- self.ownedNFTs.remove(key: withdrawID) ?? panic("missing NFT")
64 emit Withdraw(id: token.id, from: self.owner?.address)
65 return <-token
66 }
67
68 access(all) fun deposit(token: @{NonFungibleToken.NFT}) {
69 let token <- token as! @SimpleFlunks.NFT
70 let id: UInt64 = token.id
71 let oldToken <- self.ownedNFTs[id] <- token
72 emit Deposit(id: id, to: self.owner?.address)
73 destroy oldToken
74 }
75
76 access(all) view fun getIDs(): [UInt64] {
77 return self.ownedNFTs.keys
78 }
79
80 access(all) view fun borrowNFT(_ id: UInt64): &{NonFungibleToken.NFT}? {
81 return &self.ownedNFTs[id]
82 }
83
84 access(all) view fun borrowViewResolver(id: UInt64): &{ViewResolver.Resolver}? {
85 if let nft = &self.ownedNFTs[id] as &{NonFungibleToken.NFT}? {
86 return nft as &{ViewResolver.Resolver}
87 }
88 return nil
89 }
90
91 access(all) fun createEmptyCollection(): @{NonFungibleToken.Collection} {
92 return <-create Collection()
93 }
94
95 access(all) view fun getSupportedNFTTypes(): {Type: Bool} {
96 return {Type<@SimpleFlunks.NFT>(): true}
97 }
98
99 access(all) view fun isSupportedNFTType(type: Type): Bool {
100 return type == Type<@SimpleFlunks.NFT>()
101 }
102 }
103
104 // This is the key Admin resource for Task 1!
105 access(all) resource Admin {
106
107 // Step 1: Admin resource can call function mintNFT ✅
108 access(all) fun mintNFT(
109 recipient: &{NonFungibleToken.CollectionPublic},
110 name: String,
111 description: String,
112 image: String
113 ) {
114 let newNFT <- create NFT(
115 id: SimpleFlunks.totalSupply,
116 name: name,
117 description: description,
118 image: image
119 )
120
121 let recipientAddress = recipient.owner!.address
122
123 recipient.deposit(token: <-newNFT)
124
125 emit Minted(id: SimpleFlunks.totalSupply, to: recipientAddress)
126
127 SimpleFlunks.totalSupply = SimpleFlunks.totalSupply + 1
128 }
129 }
130
131 access(all) fun createEmptyCollection(nftType: Type): @{NonFungibleToken.Collection} {
132 return <-create Collection()
133 }
134
135 access(all) view fun getContractViews(resourceType: Type?): [Type] {
136 return [Type<MetadataViews.NFTCollectionData>()]
137 }
138
139 access(all) fun resolveContractView(resourceType: Type?, viewType: Type): AnyStruct? {
140 switch viewType {
141 case Type<MetadataViews.NFTCollectionData>():
142 return MetadataViews.NFTCollectionData(
143 storagePath: SimpleFlunks.CollectionStoragePath,
144 publicPath: SimpleFlunks.CollectionPublicPath,
145 publicCollection: Type<&SimpleFlunks.Collection>(),
146 publicLinkedType: Type<&SimpleFlunks.Collection>(),
147 createEmptyCollectionFunction: (fun (): @{NonFungibleToken.Collection} {
148 return <-SimpleFlunks.createEmptyCollection(nftType: Type<@SimpleFlunks.Collection>())
149 })
150 )
151 }
152 return nil
153 }
154
155 init() {
156 self.totalSupply = 0
157
158 self.CollectionStoragePath = /storage/SimpleFlunksCollection
159 self.CollectionPublicPath = /public/SimpleFlunksCollection
160 self.AdminStoragePath = /storage/SimpleFlunksAdmin
161
162 // Create and store Admin resource - This enables Step 1!
163 let admin <- create Admin()
164 self.account.storage.save(<-admin, to: self.AdminStoragePath)
165
166 emit ContractInitialized()
167 }
168}
169