From a7f89cd12207a3bab750bf94c54c415efbb1b28f Mon Sep 17 00:00:00 2001 From: Syed Ghufran Hassan Date: Wed, 28 Jan 2026 17:38:57 +0500 Subject: [PATCH] Update event-ticketing.clar fix: add proper begin blocks for print event emissions --- contracts/contracts/event-ticketing.clar | 184 +++++++++++++---------- 1 file changed, 105 insertions(+), 79 deletions(-) diff --git a/contracts/contracts/event-ticketing.clar b/contracts/contracts/event-ticketing.clar index e73a3e1..9181556 100644 --- a/contracts/contracts/event-ticketing.clar +++ b/contracts/contracts/event-ticketing.clar @@ -1,23 +1,31 @@ +;; ----------------------------------------------------------- +;; Errors +;; ----------------------------------------------------------- + (define-constant ERR_EVENT_NOT_FOUND (err u100)) (define-constant ERR_INVALID_QUANTITY (err u101)) (define-constant ERR_EVENT_CANCELLED (err u102)) (define-constant ERR_SOLD_OUT (err u103)) -(define-constant ERR_NOT_INITIALIZED (err u110)) (define-constant ERR_UNAUTHORIZED (err u111)) -(define-constant ERR_INVALID_PRICE (err u112)) (define-constant ERR_MAX_QTY_EXCEEDED (err u113)) -;; Minimal SIP-010 transfer trait (USDCx should implement this). +;; ----------------------------------------------------------- +;; Traits +;; ----------------------------------------------------------- + (define-trait sip010-ft-trait ( - (transfer (uint principal principal (optional (buff 34))) (response bool uint)) + (transfer (uint principal principal (optional (buff 34))) + (response bool uint)) ) ) -;; Counter for unique event IDs +;; ----------------------------------------------------------- +;; Storage +;; ----------------------------------------------------------- + (define-data-var next-event-id uint u1) -;; Map to store events (define-map events { event-id: uint } { @@ -26,42 +34,35 @@ city: (string-utf8 64), date: uint, max-tickets: uint, - ;; micro-USDCx (6 decimals) price-usdcx: uint, organizer: principal, tickets-sold: uint, is-cancelled: bool, - ;; event-level metadata URI (used for ticket NFTs) token-uri: (string-ascii 256) } ) -;; Map to track ticket ownership -;; key = (event-id, buyer), value = number of tickets (define-map tickets { event-id: uint, buyer: principal } uint ) ;; ----------------------------------------------------------- -;; Event Functions +;; Event Management ;; ----------------------------------------------------------- -;; Create a new event -(define-public (create-event - (name (string-utf8 64)) - (venue (string-utf8 64)) - (city (string-utf8 64)) - (date uint) - (max-tickets uint) - (price-usdcx uint) - (token-uri (string-ascii 256))) - (let - ( - (event-id (var-get next-event-id)) - ) - (asserts! (> max-tickets u0) ERR_SOLD_OUT) - ;; Store the event +(define-public (create-event + (name (string-utf8 64)) + (venue (string-utf8 64)) + (city (string-utf8 64)) + (date uint) + (max-tickets uint) + (price-usdcx uint) + (token-uri (string-ascii 256)) +) + (let ((event-id (var-get next-event-id))) + (asserts! (> max-tickets u0) ERR_INVALID_QUANTITY) + (map-set events { event-id: event-id } { @@ -77,28 +78,35 @@ token-uri: token-uri } ) - ;; Increment event ID for next event + (var-set next-event-id (+ event-id u1)) - ;; Return the new event ID - (ok event-id) + + (begin + (print { + type: "event-created", + event-id: event-id, + organizer: tx-sender, + max-tickets: max-tickets, + price-usdcx: price-usdcx, + date: date + }) + (ok event-id) + ) ) ) -;; Get event details (define-read-only (get-event (event-id uint)) (map-get? events { event-id: event-id }) ) -;; Get the counter for the next event ID (total events created + 1) (define-read-only (get-next-event-id) (ok (var-get next-event-id)) ) ;; ----------------------------------------------------------- -;; Ticketing Functions +;; Ticket Minting Helper ;; ----------------------------------------------------------- -;; Mint up to 10 ticket NFTs in a single purchase (no loops/recursion in Clarity). (define-private (mint-up-to-10 (event-id uint) (recipient principal) @@ -107,77 +115,81 @@ (quantity uint) ) (begin - (if (>= quantity u1) (begin (try! (contract-call? .event-nft mint-for-event recipient event-id (+ start-serial u0) token-uri)) true) true) - (if (>= quantity u2) (begin (try! (contract-call? .event-nft mint-for-event recipient event-id (+ start-serial u1) token-uri)) true) true) - (if (>= quantity u3) (begin (try! (contract-call? .event-nft mint-for-event recipient event-id (+ start-serial u2) token-uri)) true) true) - (if (>= quantity u4) (begin (try! (contract-call? .event-nft mint-for-event recipient event-id (+ start-serial u3) token-uri)) true) true) - (if (>= quantity u5) (begin (try! (contract-call? .event-nft mint-for-event recipient event-id (+ start-serial u4) token-uri)) true) true) - (if (>= quantity u6) (begin (try! (contract-call? .event-nft mint-for-event recipient event-id (+ start-serial u5) token-uri)) true) true) - (if (>= quantity u7) (begin (try! (contract-call? .event-nft mint-for-event recipient event-id (+ start-serial u6) token-uri)) true) true) - (if (>= quantity u8) (begin (try! (contract-call? .event-nft mint-for-event recipient event-id (+ start-serial u7) token-uri)) true) true) - (if (>= quantity u9) (begin (try! (contract-call? .event-nft mint-for-event recipient event-id (+ start-serial u8) token-uri)) true) true) - (if (>= quantity u10) (begin (try! (contract-call? .event-nft mint-for-event recipient event-id (+ start-serial u9) token-uri)) true) true) + (if (>= quantity u1) (try! (contract-call? .event-nft mint-for-event recipient event-id (+ start-serial u0) token-uri)) true) + (if (>= quantity u2) (try! (contract-call? .event-nft mint-for-event recipient event-id (+ start-serial u1) token-uri)) true) + (if (>= quantity u3) (try! (contract-call? .event-nft mint-for-event recipient event-id (+ start-serial u2) token-uri)) true) + (if (>= quantity u4) (try! (contract-call? .event-nft mint-for-event recipient event-id (+ start-serial u3) token-uri)) true) + (if (>= quantity u5) (try! (contract-call? .event-nft mint-for-event recipient event-id (+ start-serial u4) token-uri)) true) + (if (>= quantity u6) (try! (contract-call? .event-nft mint-for-event recipient event-id (+ start-serial u5) token-uri)) true) + (if (>= quantity u7) (try! (contract-call? .event-nft mint-for-event recipient event-id (+ start-serial u6) token-uri)) true) + (if (>= quantity u8) (try! (contract-call? .event-nft mint-for-event recipient event-id (+ start-serial u7) token-uri)) true) + (if (>= quantity u9) (try! (contract-call? .event-nft mint-for-event recipient event-id (+ start-serial u8) token-uri)) true) + (if (>= quantity u10) (try! (contract-call? .event-nft mint-for-event recipient event-id (+ start-serial u9) token-uri)) true) (ok true) ) ) -;; Purchase tickets for an event using USDCx (via SIP-010-style `transfer` on `payment-token`) -(define-public (purchase-ticket (event-id uint) (quantity uint) (payment-token )) - (let - ( - (event (unwrap! (map-get? events { event-id: event-id }) ERR_EVENT_NOT_FOUND)) - (organizer (get organizer event)) - (token-uri (get token-uri event)) - (sold (get tickets-sold event)) - (max (get max-tickets event)) - (price (get price-usdcx event)) - ) +;; ----------------------------------------------------------- +;; Ticket Purchase +;; ----------------------------------------------------------- + +(define-public (purchase-ticket + (event-id uint) + (quantity uint) + (payment-token ) +) + (let ( + (event (unwrap! (map-get? events { event-id: event-id }) ERR_EVENT_NOT_FOUND)) + (sold (get tickets-sold event)) + (max (get max-tickets event)) + (price (get price-usdcx event)) + (organizer (get organizer event)) + ) (asserts! (> quantity u0) ERR_INVALID_QUANTITY) (asserts! (<= quantity u10) ERR_MAX_QTY_EXCEEDED) (asserts! (not (get is-cancelled event)) ERR_EVENT_CANCELLED) (asserts! (<= (+ sold quantity) max) ERR_SOLD_OUT) - (let - ( - (required (* price quantity)) - (start-serial (+ sold u1)) - ) - ;; Transfer payment (micro-USDCx) to organizer (skip if free) + + (let ( + (required (* price quantity)) + (start-serial (+ sold u1)) + ) (if (is-eq required u0) true - (begin - (try! (contract-call? payment-token transfer required tx-sender organizer none)) - ) + (try! (contract-call? payment-token transfer required tx-sender organizer none)) ) - ;; Mint ticket NFTs - (try! (mint-up-to-10 event-id tx-sender token-uri start-serial quantity)) + (try! (mint-up-to-10 event-id tx-sender (get token-uri event) start-serial quantity)) - ;; Update tickets sold (map-set events { event-id: event-id } (merge event { tickets-sold: (+ sold quantity) }) ) - ;; Update buyer's ticket balance (convenience getter) (let ((current (default-to u0 (map-get? tickets { event-id: event-id, buyer: tx-sender })))) (map-set tickets { event-id: event-id, buyer: tx-sender } (+ current quantity)) ) - (ok { event-id: event-id, first-serial: start-serial, quantity: quantity }) + (begin + (print { + type: "ticket-purchased", + event-id: event-id, + buyer: tx-sender, + quantity: quantity, + total-paid: required, + first-serial: start-serial + }) + (ok { event-id: event-id, first-serial: start-serial, quantity: quantity }) + ) ) ) ) -;; Get ticket balance for a user -(define-read-only (get-user-tickets (event-id uint) (buyer principal)) - (default-to u0 (map-get? tickets { event-id: event-id, buyer: buyer })) -) +;; ----------------------------------------------------------- +;; Cancellation +;; ----------------------------------------------------------- -;; Cancel an event (only organizer can cancel) (define-public (cancel-event (event-id uint)) - (let - ( - (event (unwrap! (map-get? events { event-id: event-id }) ERR_EVENT_NOT_FOUND)) - ) + (let ((event (unwrap! (map-get? events { event-id: event-id }) ERR_EVENT_NOT_FOUND))) (asserts! (is-eq (get organizer event) tx-sender) ERR_UNAUTHORIZED) (asserts! (not (get is-cancelled event)) ERR_EVENT_CANCELLED) @@ -185,7 +197,21 @@ (merge event { is-cancelled: true }) ) - ;; Refund logic not implemented yet - (ok true) + (begin + (print { + type: "event-cancelled", + event-id: event-id, + organizer: tx-sender + }) + (ok true) + ) ) ) + +;; ----------------------------------------------------------- +;; Views +;; ----------------------------------------------------------- + +(define-read-only (get-user-tickets (event-id uint) (buyer principal)) + (default-to u0 (map-get? tickets { event-id: event-id, buyer: buyer })) +)