Smart Contract
Edition
A.f5b0eb433389ac3f.Edition
1import FungibleToken from 0xf233dcee88fe0abe
2
3// Common information for all copies of the same item
4pub contract Edition {
5
6 pub let CollectionStoragePath: StoragePath
7 pub let CollectionPublicPath: PublicPath
8
9 // The total amount of editions that have been created
10 pub var totalEditions: UInt64
11
12 // Struct to display and handle commissions
13 pub struct CommissionStructure {
14 pub let firstSalePercent: UFix64
15 pub let secondSalePercent: UFix64
16 pub let description: String
17
18 init(
19 firstSalePercent: UFix64,
20 secondSalePercent: UFix64,
21 description: String
22 ) {
23 self.firstSalePercent = firstSalePercent
24 self.secondSalePercent = secondSalePercent
25 self.description = description
26 }
27 }
28
29 // Events
30 pub event CreateEdition(editionId: UInt64, maxEdition: UInt64)
31 pub event ChangeCommision(editionId: UInt64)
32 pub event ChangeMaxEdition(editionId: UInt64, maxEdition: UInt64)
33
34 // Edition's status(commission and amount copies of the same item)
35 pub struct EditionStatus {
36 pub let royalty: { Address: CommissionStructure }
37 pub let editionId: UInt64
38 pub let maxEdition: UInt64
39
40 init(
41 royalty: { Address: CommissionStructure },
42 editionId: UInt64,
43 maxEdition: UInt64
44 ) {
45 self.royalty = royalty
46 self.editionId = editionId
47 // Amount copies of the same item
48 self.maxEdition = maxEdition
49 }
50 }
51
52 // Attributes one edition, where stores royalty and amount of copies
53 pub resource EditionItem {
54 pub let editionId: UInt64
55 pub var royalty: { Address: CommissionStructure }
56 // Amount copies of the same item
57 priv var maxEdition: UInt64
58
59 init(
60 royalty: { Address: CommissionStructure },
61 maxEdition: UInt64
62 ) {
63 Edition.totalEditions = Edition.totalEditions + (1 as UInt64)
64 self.royalty = royalty
65 self.editionId = Edition.totalEditions
66 self.maxEdition = maxEdition
67 }
68
69 // Get status of edition
70 pub fun getEdition(): EditionStatus {
71 return EditionStatus(
72 royalty: self.royalty,
73 editionId: self.editionId,
74 maxEdition: self.maxEdition
75 )
76 }
77
78 // Change commision
79 pub fun changeCommission(
80 royalty: { Address: CommissionStructure }
81 ) {
82 self.royalty = royalty
83 emit ChangeCommision(editionId: self.editionId)
84 }
85
86 // Change count of copies. This is used for Open Edition, because the eventual amount of copies are known only after finish of sale
87 pub fun changeMaxEdition (
88 maxEdition: UInt64
89 ) {
90 pre {
91 // Possible change this number only once after Open Edition would be completed
92 self.maxEdition < UInt64(1) : "Forbid change max edition"
93 }
94
95 self.maxEdition = maxEdition
96
97 emit ChangeMaxEdition(editionId: self.editionId, maxEdition: maxEdition)
98 }
99
100 destroy() {
101 log("destroy edition item")
102 }
103 }
104
105 // EditionCollectionPublic is a resource interface that restricts users to
106 // retreiving the edition's information
107 pub resource interface EditionCollectionPublic {
108 pub fun getEdition(_ id: UInt64): EditionStatus?
109 }
110
111 //EditionCollection contains a dictionary EditionItems and provides
112 // methods for manipulating EditionItems
113 pub resource EditionCollection: EditionCollectionPublic {
114
115 // Edition Items
116 access(account) var editionItems: @{UInt64: EditionItem}
117
118 init() {
119 self.editionItems <- {}
120 }
121
122 // Validate royalty
123 priv fun validateRoyalty(
124 royalty: { Address: CommissionStructure }
125 ) {
126 var firstSummaryPercent = 0.00
127 var secondSummaryPercent = 0.00
128
129 for key in royalty.keys {
130
131 firstSummaryPercent = firstSummaryPercent + royalty[key]!.firstSalePercent
132
133 secondSummaryPercent = secondSummaryPercent + royalty[key]!.secondSalePercent
134
135 let account = getAccount(key)
136
137 let vaultCap = account.getCapability<&{FungibleToken.Receiver}>(/public/fusdReceiver)
138
139 if !vaultCap.check() {
140 let panicMessage = "Account ".concat(key.toString()).concat(" does not provide fusd vault capability")
141 panic(panicMessage)
142 }
143 }
144
145 if firstSummaryPercent != 100.00 {
146 panic("The first summary sale percent should be 100 %")
147 }
148
149 if secondSummaryPercent >= 100.00 {
150 panic("The second summary sale percent should be less than 100 %")
151 }
152 }
153
154 // Create edition (common information for all copies of the same item)
155 pub fun createEdition(
156 royalty: { Address: CommissionStructure },
157 maxEdition: UInt64
158 ): UInt64 {
159
160 self.validateRoyalty(royalty: royalty)
161
162 let item <- create EditionItem(
163 royalty: royalty,
164 maxEdition: maxEdition
165 )
166
167 let id = item.editionId
168
169 // update the auction items dictionary with the new resources
170 let oldItem <- self.editionItems[id] <- item
171
172 destroy oldItem
173
174 emit CreateEdition(editionId: id, maxEdition: maxEdition)
175
176 return id
177 }
178
179 pub fun getEdition(_ id: UInt64): EditionStatus? {
180 if self.editionItems[id] == nil {
181 return nil
182 }
183
184 // Get the edition item resources
185 let itemRef = &self.editionItems[id] as &EditionItem?
186 return itemRef!.getEdition()
187 }
188
189 //Change commission
190 pub fun changeCommission(
191 id: UInt64,
192 royalty: { Address: CommissionStructure }
193 ) {
194 pre {
195 self.editionItems[id] != nil: "Edition does not exist"
196 }
197
198 self.validateRoyalty(royalty: royalty)
199
200 let itemRef = &self.editionItems[id] as &EditionItem?
201
202 itemRef!.changeCommission(
203 royalty: royalty
204 )
205 }
206
207 // Change count of copies. This is used for Open Edition, because the eventual amount of copies are unknown
208 pub fun changeMaxEdition(
209 id: UInt64,
210 maxEdition: UInt64
211 ) {
212 pre {
213 self.editionItems[id] != nil: "Edition does not exist"
214 }
215
216 let itemRef = &self.editionItems[id] as &EditionItem?
217 itemRef!.changeMaxEdition(
218 maxEdition: maxEdition
219 )
220 }
221
222 destroy() {
223 log("destroy edition collection")
224 // destroy the empty resources
225 destroy self.editionItems
226 }
227 }
228
229 // createEditionCollection returns a new createEditionCollection resource to the caller
230 priv fun createEditionCollection(): @EditionCollection {
231 let editionCollection <- create EditionCollection()
232
233 return <- editionCollection
234 }
235
236 init() {
237 self.totalEditions = (0 as UInt64)
238 self.CollectionPublicPath = /public/bloctoXtinglesEdition
239 self.CollectionStoragePath = /storage/bloctoXtinglesEdition
240
241 let edition <- Edition.createEditionCollection()
242 self.account.save(<- edition, to: Edition.CollectionStoragePath)
243 self.account.link<&{Edition.EditionCollectionPublic}>(Edition.CollectionPublicPath, target: Edition.CollectionStoragePath)
244 }
245}