Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions mgt-system/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

settings/Mainnet.toml
settings/Testnet.toml
history.txt
4 changes: 4 additions & 0 deletions mgt-system/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

{
"deno.enable": true,
}
18 changes: 18 additions & 0 deletions mgt-system/.vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@

{
"version": "2.0.0",
"tasks": [
{
"label": "check contracts",
"group": "test",
"type": "shell",
"command": "clarinet check"
},
{
"label": "test contracts",
"group": "test",
"type": "shell",
"command": "clarinet test"
}
]
}
11 changes: 11 additions & 0 deletions mgt-system/Clarinet.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[project]
name = "mgt-system"
authors = []
description = ""
telemetry = true
requirements = []
analysis = ["check_checker"]
costs_version = 2
[contracts.smartgrid]
path = "contracts/smartgrid.clar"
depends_on = []
333 changes: 333 additions & 0 deletions mgt-system/contracts/smartgrid.clar
Original file line number Diff line number Diff line change
@@ -0,0 +1,333 @@
;; Smart Grid Management System
;; Manages energy production, consumption, trading, and grid balance

;; Constants
(define-constant contract-owner tx-sender)
(define-constant err-owner-only (err u100))
(define-constant err-not-found (err u101))
(define-constant err-unauthorized (err u102))
(define-constant err-insufficient-energy (err u103))
(define-constant err-invalid-amount (err u104))
(define-constant err-already-exists (err u105))
(define-constant err-inactive (err u106))
(define-constant err-insufficient-balance (err u107))
(define-constant err-invalid-input (err u108))

;; Data Variables
(define-data-var grid-operator principal contract-owner)
(define-data-var base-energy-price uint u100)
(define-data-var total-grid-capacity uint u1000000)
(define-data-var current-grid-load uint u0)
(define-data-var emergency-mode bool false)

;; Data Maps
(define-map energy-producers
principal
{
capacity: uint,
current-production: uint,
total-produced: uint,
energy-type: (string-ascii 20),
active: bool,
reputation-score: uint
}
)

(define-map energy-consumers
principal
{
consumption-limit: uint,
total-consumed: uint,
current-usage: uint,
balance: uint,
active: bool
}
)

(define-map energy-storage
principal
{
capacity: uint,
stored-amount: uint,
charge-rate: uint,
discharge-rate: uint
}
)

(define-map energy-trades
uint
{
seller: principal,
buyer: principal,
amount: uint,
price: uint,
timestamp: uint,
completed: bool
}
)

(define-map grid-metrics
uint
{
timestamp: uint,
total-production: uint,
total-consumption: uint,
peak-load: uint,
efficiency-rating: uint
}
)

(define-data-var trade-nonce uint u0)
(define-data-var metrics-nonce uint u0)

;; Read-only functions
(define-read-only (get-producer-info (producer principal))
(ok (map-get? energy-producers producer))
)

(define-read-only (get-consumer-info (consumer principal))
(ok (map-get? energy-consumers consumer))
)

(define-read-only (get-storage-info (storage principal))
(ok (map-get? energy-storage storage))
)

(define-read-only (get-trade-info (trade-id uint))
(ok (map-get? energy-trades trade-id))
)

(define-read-only (get-grid-status)
(ok {
operator: (var-get grid-operator),
capacity: (var-get total-grid-capacity),
current-load: (var-get current-grid-load),
base-price: (var-get base-energy-price),
emergency: (var-get emergency-mode),
utilization: (/ (* (var-get current-grid-load) u100) (var-get total-grid-capacity))
})
)

(define-read-only (get-dynamic-price)
(let ((load (var-get current-grid-load))
(capacity (var-get total-grid-capacity))
(base-price (var-get base-energy-price)))
(if (var-get emergency-mode)
(ok (* base-price u3))
(ok (+ base-price (/ (* base-price load) (* capacity u2))))
)
)
)

(define-read-only (get-metrics (metrics-id uint))
(ok (map-get? grid-metrics metrics-id))
)

;; Public functions - Registration
(define-public (register-producer (capacity uint) (energy-type (string-ascii 20)))
(let ((validated-type (if (is-eq energy-type "solar") "solar"
(if (is-eq energy-type "wind") "wind"
(if (is-eq energy-type "hydro") "hydro"
(if (is-eq energy-type "nuclear") "nuclear"
(if (is-eq energy-type "geothermal") "geothermal"
(if (is-eq energy-type "biomass") "biomass"
(if (is-eq energy-type "natural-gas") "natural-gas"
"solar")))))))))
(asserts! (> capacity u0) err-invalid-amount)
(asserts! (is-none (map-get? energy-producers tx-sender)) err-already-exists)
(ok (map-set energy-producers tx-sender {
capacity: capacity,
current-production: u0,
total-produced: u0,
energy-type: validated-type,
active: true,
reputation-score: u100
}))
)
)

(define-public (register-consumer (consumption-limit uint))
(begin
(asserts! (> consumption-limit u0) err-invalid-amount)
(asserts! (is-none (map-get? energy-consumers tx-sender)) err-already-exists)
(ok (map-set energy-consumers tx-sender {
consumption-limit: consumption-limit,
total-consumed: u0,
current-usage: u0,
balance: u0,
active: true
}))
)
)

(define-public (register-storage (capacity uint) (charge-rate uint) (discharge-rate uint))
(begin
(asserts! (and (> capacity u0) (> charge-rate u0) (> discharge-rate u0)) err-invalid-amount)
(ok (map-set energy-storage tx-sender {
capacity: capacity,
stored-amount: u0,
charge-rate: charge-rate,
discharge-rate: discharge-rate
}))
)
)

;; Energy production and consumption
(define-public (report-production (amount uint))
(let ((producer (unwrap! (map-get? energy-producers tx-sender) err-not-found)))
(asserts! (get active producer) err-inactive)
(asserts! (<= amount (get capacity producer)) err-invalid-amount)
(map-set energy-producers tx-sender (merge producer {
current-production: amount,
total-produced: (+ (get total-produced producer) amount)
}))
(var-set current-grid-load (+ (var-get current-grid-load) amount))
(ok true)
)
)

(define-public (consume-energy (amount uint))
(let ((consumer (unwrap! (map-get? energy-consumers tx-sender) err-not-found))
(price (unwrap-panic (get-dynamic-price)))
(cost (* amount price)))
(asserts! (get active consumer) err-inactive)
(asserts! (<= amount (get consumption-limit consumer)) err-invalid-amount)
(asserts! (>= (get balance consumer) cost) err-insufficient-balance)
(asserts! (>= (var-get current-grid-load) amount) err-insufficient-energy)
(map-set energy-consumers tx-sender (merge consumer {
current-usage: amount,
total-consumed: (+ (get total-consumed consumer) amount),
balance: (- (get balance consumer) cost)
}))
(var-set current-grid-load (- (var-get current-grid-load) amount))
(ok true)
)
)

;; Storage operations
(define-public (charge-storage (amount uint))
(let ((storage (unwrap! (map-get? energy-storage tx-sender) err-not-found)))
(asserts! (<= amount (get charge-rate storage)) err-invalid-amount)
(asserts! (<= (+ (get stored-amount storage) amount) (get capacity storage)) err-invalid-amount)
(asserts! (>= (var-get current-grid-load) amount) err-insufficient-energy)
(map-set energy-storage tx-sender (merge storage {
stored-amount: (+ (get stored-amount storage) amount)
}))
(var-set current-grid-load (- (var-get current-grid-load) amount))
(ok true)
)
)

(define-public (discharge-storage (amount uint))
(let ((storage (unwrap! (map-get? energy-storage tx-sender) err-not-found)))
(asserts! (<= amount (get discharge-rate storage)) err-invalid-amount)
(asserts! (>= (get stored-amount storage) amount) err-insufficient-energy)
(map-set energy-storage tx-sender (merge storage {
stored-amount: (- (get stored-amount storage) amount)
}))
(var-set current-grid-load (+ (var-get current-grid-load) amount))
(ok true)
)
)

;; Energy trading
(define-public (create-trade (buyer principal) (amount uint) (price uint))
(let ((producer (unwrap! (map-get? energy-producers tx-sender) err-not-found))
(buyer-data (unwrap! (map-get? energy-consumers buyer) err-not-found))
(trade-id (var-get trade-nonce)))
(asserts! (get active producer) err-inactive)
(asserts! (get active buyer-data) err-inactive)
(asserts! (> amount u0) err-invalid-amount)
(asserts! (> price u0) err-invalid-amount)
(asserts! (>= (get current-production producer) amount) err-insufficient-energy)
(map-set energy-trades trade-id {
seller: tx-sender,
buyer: buyer,
amount: amount,
price: price,
timestamp: block-height,
completed: false
})
(var-set trade-nonce (+ trade-id u1))
(ok trade-id)
)
)

(define-public (complete-trade (trade-id uint))
(let ((trade (unwrap! (map-get? energy-trades trade-id) err-not-found))
(consumer (unwrap! (map-get? energy-consumers tx-sender) err-not-found)))
(asserts! (is-eq tx-sender (get buyer trade)) err-unauthorized)
(asserts! (not (get completed trade)) err-already-exists)
(asserts! (>= (get balance consumer) (get price trade)) err-insufficient-balance)
(map-set energy-consumers tx-sender (merge consumer {
balance: (- (get balance consumer) (get price trade))
}))
(map-set energy-trades trade-id (merge trade {completed: true}))
(ok true)
)
)

;; Admin functions
(define-public (add-consumer-balance (target-consumer principal) (amount uint))
(let ((consumer-data (unwrap! (map-get? energy-consumers target-consumer) err-not-found))
(validated-amount (if (and (> amount u0) (<= amount u1000000)) amount u0)))
(asserts! (> validated-amount u0) err-invalid-amount)
(ok (map-set energy-consumers target-consumer (merge consumer-data {
balance: (+ (get balance consumer-data) validated-amount)
})))
)
)

(define-public (set-base-price (new-price uint))
(begin
(asserts! (is-eq tx-sender (var-get grid-operator)) err-owner-only)
(asserts! (> new-price u0) err-invalid-amount)
(ok (var-set base-energy-price new-price))
)
)

(define-public (toggle-emergency-mode)
(begin
(asserts! (is-eq tx-sender (var-get grid-operator)) err-owner-only)
(ok (var-set emergency-mode (not (var-get emergency-mode))))
)
)

(define-public (record-metrics (prod uint) (cons uint) (peak-load uint) (eff uint))
(let ((metrics-id (var-get metrics-nonce))
(validated-eff (if (<= eff u100) eff u100))
(validated-peak (if (<= peak-load (var-get total-grid-capacity)) peak-load u0)))
(asserts! (is-eq tx-sender (var-get grid-operator)) err-owner-only)
(map-set grid-metrics metrics-id {
timestamp: block-height,
total-production: prod,
total-consumption: cons,
peak-load: validated-peak,
efficiency-rating: validated-eff
})
(var-set metrics-nonce (+ metrics-id u1))
(ok metrics-id)
)
)

(define-public (update-producer-reputation (target-producer principal) (new-score uint))
(let ((producer-data (unwrap! (map-get? energy-producers target-producer) err-not-found))
(validated-score (if (<= new-score u100) new-score u100)))
(asserts! (is-eq tx-sender (var-get grid-operator)) err-owner-only)
(ok (map-set energy-producers target-producer (merge producer-data {
reputation-score: validated-score
})))
)
)

(define-public (deactivate-participant (target principal) (is-producer bool))
(begin
(asserts! (is-eq tx-sender (var-get grid-operator)) err-owner-only)
(if is-producer
(let ((producer (unwrap! (map-get? energy-producers target) err-not-found)))
(ok (map-set energy-producers target (merge producer {active: false}))))
(let ((consumer (unwrap! (map-get? energy-consumers target) err-not-found)))
(ok (map-set energy-consumers target (merge consumer {active: false}))))
)
)
)
Loading