;; title: sbtc-reputation-oracle
;; version:
;; summary:
;; description:
;; Music Royalty Distribution and Rights Management System
;; This contract manages the transparent distribution of music royalties among artists,
;; producers, and rights holders with secure tracking of payments and earnings.
;; Error constants
(define-constant ERR-UNAUTHORIZED-ACCESS (err u100))
(define-constant ERR-INVALID-SHARE-VALUE (err u101))
(define-constant ERR-TRACK-ALREADY-EXISTS (err u102))
(define-constant ERR-TRACK-NOT-FOUND (err u103))
(define-constant ERR-PAYMENT-SHORTAGE (err u104))
(define-constant ERR-INVALID-STAKEHOLDER (err u105))
(define-constant ERR-DISBURSEMENT-FAILED (err u106))
(define-constant ERR-INVALID-STRING-SIZE (err u107))
(define-constant ERR-INVALID-TRACK-NAME (err u108))
(define-constant ERR-INVALID-MEMBER-TYPE (err u109))
(define-constant ERR-INVALID-PERFORMER (err u110))
(define-constant ERR-INVALID-MANAGER (err u111))
;; Data structures
(define-map track-catalog
{ track-id: uint }
{
track-name: (string-ascii 50),
performer: principal,
lifetime-revenue: uint,
registration-date: uint,
distribution-enabled: bool
}
)
(define-map revenue-shares
{ track-id: uint, stakeholder: principal }
{
percentage-share: uint,
member-type: (string-ascii 20),
earned-to-date: uint
}
)
;; State variables
(define-data-var catalog-size uint u0)
(define-data-var catalog-manager principal tx-sender)
;; Read-only functions - Data access
(define-read-only (get-track-info (track-id uint))
(map-get? track-catalog { track-id: track-id })
)
(define-read-only (get-stakeholder-info (track-id uint) (stakeholder principal))
(map-get? revenue-shares { track-id: track-id, stakeholder: stakeholder })
)
(define-read-only (get-catalog-size)
(var-get catalog-size)
)
(define-read-only (get-track-stakeholders (track-id uint))
(let (
(track-info (get-track-info track-id))
(main-performer (match track-info record (get performer record) tx-sender))
)
(let ((stakeholder-data (get-stakeholder-info track-id main-performer)))
(match stakeholder-data share
(list {
stakeholder: main-performer,
percentage-share: (get percentage-share share)
})
(list))))
)
;; Private validation functions
(define-private (is-valid-share-data (share {
percentage-share: uint,
member-type: (string-ascii 20),
earned-to-date: uint
}))
(> (get percentage-share share) u0)
)
(define-private (is-catalog-manager)
(is-eq tx-sender (var-get catalog-manager))
)
(define-private (validate-percentage-range (percentage uint))
(and (>= percentage u0) (<= percentage u100))
)
(define-private (validate-string-input (input (string-ascii 50)))
(let ((string-length (len input)))
(and (> string-length u0) (<= string-length u50))))
(define-private (validate-member-type (type-value (string-ascii 20)))
(let ((type-length (len type-value)))
(and (> type-length u0) (<= type-length u20))))
(define-private (validate-stakeholder-address (address principal))
(and
(not (is-eq address tx-sender))
(not (is-eq address (var-get catalog-manager)))
))
;; Private payment processing functions
(define-private (process-share-payment
(allocation {stakeholder: principal, percentage-share: uint})
(payout-amount uint))
(let (
(recipient-share (/ (* payout-amount (get percentage-share allocation)) u100))
)
(if (> recipient-share u0)
(match (stx-transfer? recipient-share tx-sender (get stakeholder allocation))
success payout-amount
error u0)
u0))
)
(define-private (execute-payments (track-id uint) (payout-amount uint))
(let (
(stakeholder-list (get-track-stakeholders track-id))
(total-distributed (fold process-share-payment
stakeholder-list
payout-amount))
)
(begin
(asserts! (> (len stakeholder-list) u0) ERR-TRACK-NOT-FOUND)
(asserts! (> total-distributed u0) ERR-DISBURSEMENT-FAILED)
(ok total-distributed)))
)
;; Public functions - Administrative
(define-public (register-track (track-name (string-ascii 50)) (performer principal))
(let (
(new-track-id (+ (var-get catalog-size) u1))
)
(begin
(asserts! (is-catalog-manager) ERR-UNAUTHORIZED-ACCESS)
(asserts! (validate-string-input track-name) ERR-INVALID-TRACK-NAME)
(asserts! (validate-stakeholder-address performer) ERR-INVALID-PERFORMER)
(map-set track-catalog
{ track-id: new-track-id }
{
track-name: track-name,
performer: performer,
lifetime-revenue: u0,
registration-date: stacks-block-height,
distribution-enabled: true
}
)
(var-set catalog-size new-track-id)
(ok new-track-id)))
)
(define-public (set-share-allocation
(track-id uint)
(stakeholder principal)
(percentage-share uint)
(member-type (string-ascii 20)))
(let (
(track-data (get-track-info track-id))
)
(begin
(asserts! (is-some track-data) ERR-TRACK-NOT-FOUND)
(asserts! (validate-percentage-range percentage-share) ERR-INVALID-SHARE-VALUE)
(asserts! (validate-member-type member-type) ERR-INVALID-MEMBER-TYPE)
(asserts! (validate-stakeholder-address stakeholder) ERR-INVALID-STAKEHOLDER)
(map-set revenue-shares
{ track-id: track-id, stakeholder: stakeholder }
{
percentage-share: percentage-share,
member-type: member-type,
earned-to-date: u0
}
)
(ok true)))
)
(define-public (set-track-status (track-id uint) (status-enabled bool))
(let (
(track-data (get-track-info track-id))
)
(begin
(asserts! (is-catalog-manager) ERR-UNAUTHORIZED-ACCESS)
(asserts! (is-some track-data) ERR-TRACK-NOT-FOUND)
(map-set track-catalog
{ track-id: track-id }
(merge (unwrap-panic track-data)
{ distribution-enabled: status-enabled }
)
)
(ok true)))
)
(define-public (assign-manager (new-manager principal))
(begin
(asserts! (is-catalog-manager) ERR-UNAUTHORIZED-ACCESS)
(asserts! (validate-stakeholder-address new-manager) ERR-INVALID-MANAGER)
(var-set catalog-manager new-manager)
(ok true))
)
;; Public functions - Payment processing
(define-public (distribute-royalties (track-id uint) (royalty-amount uint))
(let (
(track-data (get-track-info track-id))
)
(begin
(asserts! (is-some track-data) ERR-TRACK-NOT-FOUND)
(asserts! (>= (stx-get-balance tx-sender) royalty-amount) ERR-PAYMENT-SHORTAGE)
(try! (execute-payments track-id royalty-amount))
(map-set track-catalog
{ track-id: track-id }
(merge (unwrap-panic track-data)
{ lifetime-revenue: (+ (get lifetime-revenue (unwrap-panic track-data)) royalty-amount) }
)
)
(ok true)))
)
;; Contract initialization
(begin
(var-set catalog-size u0))