Source Code

(define-constant ERR-NOT-AUTHORIZED (err u100))
(define-constant ERR-ARTWORK-NOT-FOUND (err u101))
(define-constant ERR-LISTING-NOT-FOUND (err u102))
(define-constant ERR-INSUFFICIENT-FUNDS (err u103))

(define-map artworks
  { artwork-id: uint }
  {
    title: (string-ascii 100),
    artist: (string-ascii 100),
    creation-year: uint,
    medium: (string-ascii 50),
    total-shares: uint,
    owner: principal,
    verified: bool,
    listed: bool
  }
)

(define-map artwork-shares
  { artwork-id: uint, holder: principal }
  uint
)

(define-map listings
  { listing-id: uint }
  {
    artwork-id: uint,
    seller: principal,
    shares-amount: uint,
    price-per-share: uint,
    active: bool,
    created-at: uint
  }
)

(define-data-var artwork-nonce uint u0)
(define-data-var listing-nonce uint u0)

(define-public (tokenize-artwork
  (title (string-ascii 100))
  (artist (string-ascii 100))
  (creation-year uint)
  (medium (string-ascii 50))
  (total-shares uint)
)
  (let ((artwork-id (var-get artwork-nonce)))
    (map-set artworks
      { artwork-id: artwork-id }
      {
        title: title,
        artist: artist,
        creation-year: creation-year,
        medium: medium,
        total-shares: total-shares,
        owner: tx-sender,
        verified: false,
        listed: false
      }
    )
    (map-set artwork-shares { artwork-id: artwork-id, holder: tx-sender } total-shares)
    (var-set artwork-nonce (+ artwork-id u1))
    (ok artwork-id)
  )
)

(define-public (create-listing (artwork-id uint) (shares uint) (price uint))
  (let (
    (listing-id (var-get listing-nonce))
    (holder-shares (default-to u0 (map-get? artwork-shares { artwork-id: artwork-id, holder: tx-sender })))
  )
    (asserts! (>= holder-shares shares) ERR-INSUFFICIENT-FUNDS)
    (map-set listings
      { listing-id: listing-id }
      {
        artwork-id: artwork-id,
        seller: tx-sender,
        shares-amount: shares,
        price-per-share: price,
        active: true,
        created-at: stacks-block-height
      }
    )
    (var-set listing-nonce (+ listing-id u1))
    (ok listing-id)
  )
)

(define-public (purchase-shares (listing-id uint) (shares uint))
  (let (
    (listing (unwrap! (map-get? listings { listing-id: listing-id }) ERR-LISTING-NOT-FOUND))
    (seller-shares (default-to u0 (map-get? artwork-shares { artwork-id: (get artwork-id listing), holder: (get seller listing) })))
    (buyer-shares (default-to u0 (map-get? artwork-shares { artwork-id: (get artwork-id listing), holder: tx-sender })))
  )
    (asserts! (get active listing) ERR-LISTING-NOT-FOUND)
    (asserts! (>= (get shares-amount listing) shares) ERR-INSUFFICIENT-FUNDS)
    (map-set artwork-shares
      { artwork-id: (get artwork-id listing), holder: (get seller listing) }
      (- seller-shares shares)
    )
    (map-set artwork-shares
      { artwork-id: (get artwork-id listing), holder: tx-sender }
      (+ buyer-shares shares)
    )
    (ok true)
  )
)

(define-read-only (get-artwork-info (artwork-id uint))
  (map-get? artworks { artwork-id: artwork-id })
)

(define-read-only (get-shares (artwork-id uint) (holder principal))
  (ok (default-to u0 (map-get? artwork-shares { artwork-id: artwork-id, holder: holder })))
)

(define-read-only (get-listing-info (listing-id uint))
  (map-get? listings { listing-id: listing-id })
)

(define-public (verify-artwork (artwork-id uint))
  (let ((artwork (unwrap! (map-get? artworks { artwork-id: artwork-id }) ERR-ARTWORK-NOT-FOUND)))
    (ok (map-set artworks
      { artwork-id: artwork-id }
      (merge artwork { verified: true })
    ))
  )
)

Functions (7)

FunctionAccessArgs
tokenize-artworkpublictitle: (string-ascii 100
create-listingpublicartwork-id: uint, shares: uint, price: uint
purchase-sharespubliclisting-id: uint, shares: uint
get-artwork-inforead-onlyartwork-id: uint
get-sharesread-onlyartwork-id: uint, holder: principal
get-listing-inforead-onlylisting-id: uint
verify-artworkpublicartwork-id: uint