Source Code

;; title: TickStx Counter Contract
;; version: 1.0.0
;; summary: A simple counter contract demonstrating Clarity fundamentals
;; description: This contract implements a global counter that can be incremented,
;; decremented, and reset. It demonstrates public vs read-only functions, mutable
;; state management, access control, and error handling in Clarity.

;; ========================================
;; Constants
;; ========================================

;; Contract owner - set to deployer's address
(define-constant CONTRACT_OWNER tx-sender)

;; Error codes
(define-constant ERR_UNAUTHORIZED (err u100))
(define-constant ERR_UNDERFLOW (err u101))
(define-constant ERR_INVALID_AMOUNT (err u104))

;; ========================================
;; Data Variables
;; ========================================

;; The global counter - starts at zero
(define-data-var counter uint u0)

;; ========================================
;; Public Functions
;; ========================================

;; Increments the counter by 1
;; @returns (response uint uint) - The new counter value on success
(define-public (increment)
  (let (
      (current-value (var-get counter))
      (new-value (+ current-value u1))
    )
    (var-set counter new-value)
    (ok new-value)
  )
)

;; Increments the counter by a specified amount
;; @param amount - The amount to add to the counter (must be > 0)
;; @returns (response uint uint) - The new counter value on success
(define-public (increment-by (amount uint))
  (begin
    ;; Validate amount is greater than zero
    (asserts! (> amount u0) ERR_INVALID_AMOUNT)

    (let (
        (current-value (var-get counter))
        (new-value (+ current-value amount))
      )
      (var-set counter new-value)
      (ok new-value)
    )
  )
)

;; Decrements the counter by 1
;; @returns (response uint uint) - The new counter value on success
;; @error ERR_UNDERFLOW if counter is already at zero
(define-public (decrement)
  (let ((current-value (var-get counter)))
    ;; Check for underflow - counter must be greater than 0
    (asserts! (> current-value u0) ERR_UNDERFLOW)

    (let ((new-value (- current-value u1)))
      (var-set counter new-value)
      (ok new-value)
    )
  )
)

;; Decrements the counter by a specified amount
;; @param amount - The amount to subtract from the counter (must be > 0)
;; @returns (response uint uint) - The new counter value on success
;; @error ERR_UNDERFLOW if counter < amount
;; @error ERR_INVALID_AMOUNT if amount is zero
(define-public (decrement-by (amount uint))
  (begin
    ;; Validate amount is greater than zero
    (asserts! (> amount u0) ERR_INVALID_AMOUNT)

    (let ((current-value (var-get counter)))
      ;; Check for underflow - counter must be >= amount
      (asserts! (>= current-value amount) ERR_UNDERFLOW)

      (let ((new-value (- current-value amount)))
        (var-set counter new-value)
        (ok new-value)
      )
    )
  )
)

;; Resets the counter to zero
;; Only the contract owner can call this function
;; @returns (response bool uint) - true on success
;; @error ERR_UNAUTHORIZED if caller is not the owner
(define-public (reset)
  (begin
    ;; Check if caller is the contract owner
    (asserts! (is-eq tx-sender CONTRACT_OWNER) ERR_UNAUTHORIZED)

    ;; Reset counter to zero
    (var-set counter u0)
    (ok true)
  )
)

;; ========================================
;; Read-Only Functions
;; ========================================

;; Gets the current counter value
;; @returns uint - The current counter value
(define-read-only (get-counter)
  (var-get counter)
)

;; Gets the contract owner's principal
;; @returns principal - The contract owner's address
(define-read-only (get-owner)
  CONTRACT_OWNER
)

Functions (7)

FunctionAccessArgs
resetpublic
get-counterread-only
incrementpublic
increment-bypublicamount: uint
decrementpublic
decrement-bypublicamount: uint
get-ownerread-only