Smart Contract
ShowUpEvents
A.a19273383554e1e1.ShowUpEvents
1access(all) contract ShowUpEvents {
2
3 // Events
4 access(all) event ContractInitialized()
5 access(all) event EventCreated(eventId: String, creator: Address, title: String, stakeAmount: UFix64)
6 access(all) event UserStaked(eventId: String, user: Address, amount: UFix64)
7 access(all) event UserCheckedIn(eventId: String, user: Address)
8 access(all) event StakeReturned(eventId: String, user: Address, amount: UFix64)
9
10 // Paths
11 access(all) let EventsStoragePath: StoragePath
12 access(all) let EventsPublicPath: PublicPath
13
14 // Event Data Structure
15 access(all) struct EventData {
16 access(all) let id: String
17 access(all) let title: String
18 access(all) let description: String
19 access(all) let date: String
20 access(all) let location: String
21 access(all) let stakeAmount: UFix64
22 access(all) let maxAttendees: UInt32
23 access(all) var currentAttendees: UInt32
24 access(all) let creator: Address
25 access(all) var isActive: Bool
26 access(all) let attendees: {Address: Bool} // Address -> isCheckedIn
27
28 init(
29 id: String,
30 title: String,
31 description: String,
32 date: String,
33 location: String,
34 stakeAmount: UFix64,
35 maxAttendees: UInt32,
36 creator: Address
37 ) {
38 self.id = id
39 self.title = title
40 self.description = description
41 self.date = date
42 self.location = location
43 self.stakeAmount = stakeAmount
44 self.maxAttendees = maxAttendees
45 self.currentAttendees = 0
46 self.creator = creator
47 self.isActive = true
48 self.attendees = {}
49 }
50
51 access(contract) fun addAttendee(user: Address) {
52 self.attendees[user] = false
53 self.currentAttendees = self.currentAttendees + 1
54 }
55
56 access(contract) fun checkInUser(user: Address) {
57 self.attendees[user] = true
58 }
59 }
60
61 // Stake Data Structure
62 access(all) struct StakeData {
63 access(all) let eventId: String
64 access(all) let user: Address
65 access(all) let amount: UFix64
66 access(all) let timestamp: UFix64
67 access(all) var isCheckedIn: Bool
68
69 init(eventId: String, user: Address, amount: UFix64) {
70 self.eventId = eventId
71 self.user = user
72 self.amount = amount
73 self.timestamp = getCurrentBlock().timestamp
74 self.isCheckedIn = false
75 }
76
77 access(contract) fun checkIn() {
78 self.isCheckedIn = true
79 }
80 }
81
82 // Public Interface for Events Collection
83 access(all) resource interface EventsCollectionPublic {
84 access(all) fun getEvent(eventId: String): EventData?
85 access(all) fun getAllEvents(): [EventData]
86 access(all) fun getUserStakes(user: Address): [StakeData]
87 }
88
89 // Events Collection Resource
90 access(all) resource EventsCollection: EventsCollectionPublic {
91 access(all) var events: {String: EventData}
92 access(all) var stakes: {Address: [StakeData]}
93
94 init() {
95 self.events = {}
96 self.stakes = {}
97 }
98
99 access(all) fun createEvent(
100 title: String,
101 description: String,
102 date: String,
103 location: String,
104 stakeAmount: UFix64,
105 maxAttendees: UInt32
106 ): String {
107 let creator = self.owner?.address ?? panic("No owner address")
108 let eventId = title.concat("-").concat(getCurrentBlock().timestamp.toString())
109
110 let eventData = EventData(
111 id: eventId,
112 title: title,
113 description: description,
114 date: date,
115 location: location,
116 stakeAmount: stakeAmount,
117 maxAttendees: maxAttendees,
118 creator: creator
119 )
120
121 self.events[eventId] = eventData
122
123 emit EventCreated(
124 eventId: eventId,
125 creator: creator,
126 title: title,
127 stakeAmount: stakeAmount
128 )
129
130 return eventId
131 }
132
133 access(all) fun stakeForEvent(eventId: String, staker: Address, amount: UFix64) {
134 pre {
135 self.events[eventId] != nil: "Event does not exist"
136 self.events[eventId]!.isActive: "Event is not active"
137 self.events[eventId]!.currentAttendees < self.events[eventId]!.maxAttendees: "Event is full"
138 }
139
140 // Check if user already staked
141 let userStakes = self.stakes[staker] ?? []
142 for stake in userStakes {
143 if stake.eventId == eventId {
144 panic("User already staked for this event")
145 }
146 }
147
148 let stake = StakeData(eventId: eventId, user: staker, amount: amount)
149
150 if self.stakes[staker] == nil {
151 self.stakes[staker] = []
152 }
153 self.stakes[staker]!.append(stake)
154
155 // Add user to event attendees
156 self.events[eventId]!.addAttendee(user: staker)
157
158 emit UserStaked(eventId: eventId, user: staker, amount: amount)
159 }
160
161 access(all) fun checkInUser(eventId: String, user: Address) {
162 pre {
163 self.events[eventId] != nil: "Event does not exist"
164 }
165
166 // Mark user as checked in the event
167 self.events[eventId]!.checkInUser(user: user)
168
169 // Mark stake as checked in
170 if let userStakes = self.stakes[user] {
171 for i, stake in userStakes {
172 if stake.eventId == eventId {
173 userStakes[i].checkIn()
174 break
175 }
176 }
177 }
178
179 emit UserCheckedIn(eventId: eventId, user: user)
180 }
181
182 access(all) fun getEvent(eventId: String): EventData? {
183 return self.events[eventId]
184 }
185
186 access(all) fun getAllEvents(): [EventData] {
187 return self.events.values
188 }
189
190 access(all) fun getUserStakes(user: Address): [StakeData] {
191 return self.stakes[user] ?? []
192 }
193 }
194
195 // Create Events Collection
196 access(all) fun createEventsCollection(): @EventsCollection {
197 return <-create EventsCollection()
198 }
199
200 init() {
201 // Set storage paths
202 self.EventsStoragePath = /storage/ShowUpEventsCollection
203 self.EventsPublicPath = /public/ShowUpEventsCollection
204
205 // Create and store the events collection
206 let collection <- create EventsCollection()
207 self.account.storage.save(<-collection, to: self.EventsStoragePath)
208
209 // Create public capability
210 let cap = self.account.capabilities.storage.issue<&EventsCollection>(self.EventsStoragePath)
211 self.account.capabilities.publish(cap, at: self.EventsPublicPath)
212
213 emit ContractInitialized()
214 }
215}
216