This Clarity smart contract allows for the updating of a notifier through an election vote using a threshold, where each participant can vote only once. The contract starts by checking if the vote for the notifier is already active and sets the start and end block height
for the voting period.
If one miner meets the threshold while voting, the voting ends and it is elected as the new notifier.
Once the voting period ends, the contract computes the maximum votes received by each proposed notifier, and if a proposed notifier receives more than half the votes, it is selected as the new notifier. The contract also deletes all previous entries for the voting period and sets the notifier-previous-entries-removed flag to true. Participants can vote for a notifier using the vote-notifier
function, which checks for voting permission, whether the vote is within the voting period, and if the participant has already voted. The contract also includes election functions for accepting and rejecting votes based on the threshold and number of voters.
Copy ;; UPDATE NOTIFIER
(define-public (start-vote-notifier)
(begin
(asserts! ( not (var-get notifier-vote-active)) err-vote-started-already)
(var-set notifier-vote-start-block block-height)
(var-set notifier-vote-end-block ( + (var-get notifier-vote-start-block) (var-get notifier-election-blocks-to-pass)))
(var-set notifier-vote-active true)
( if (var-get notifier-previous-entries-removed)
(begin
(ok (var-set notifier-previous-entries-removed false)))
(end-vote-notifier))))
(define-public (end-vote-notifier)
(begin
(asserts! ( >= block-height (var-get notifier-vote-end-block)) err-voting-still-active)
(get-max-votes-number-notifier)
( if ( > (var-get max-votes-notifier) ( / (var-get k) u2))
(var-set notifier (var-get max-voted-proposed-notifier))
false)
(delete-all-notifier-entries)
(var-set notifier-vote-active false)
(ok true)))
(define-private (get-max-votes-number-notifier)
( map compare-votes-number-notifier (var-get proposed-notifiers-list)))
(define-private (compare-votes-number-notifier (proposed-notifier principal))
(if (> (unwrap-panic (get votes-number (map-get? map-votes-notifier {voted-notifier: proposed-notifier}))) (var-get max-votes-notifier))
(begin
(var-set max-votes-notifier (unwrap-panic (get votes-number (map-get? map-votes-notifier {voted-notifier: proposed-notifier}))))
(var-set max-voted-proposed-notifier proposed-notifier))
(if (is-eq (unwrap-panic (get votes-number (map-get? map-votes-notifier {voted-notifier: proposed-notifier}))) (var-get max-votes-notifier))
( if
( <
(unwrap-panic ( get block-height (map-get? map-block-joined {address : proposed-notifier})))
(unwrap-panic (get block-height (map-get? map-block-joined {address: (var-get max-voted-proposed-notifier)}))))
(begin
(var-set max-voted-proposed-notifier proposed-notifier))
false)
false)))
(define-private (delete-all-notifier-entries)
(begin
( map delete-one-notifier-entry (var-get miners-list))
(var-set notifier-previous-entries-removed true)))
(define-private (delete-one-notifier-entry (miner principal))
(begin
(map-delete map-voted-update-notifier {miner-who-voted : miner})
(map-delete map-votes-notifier {voted-notifier : miner})))
(define-public (vote-notifier (voted-notifier principal))
(begin
(asserts! (and (is-some (get value (map-get? map-is-miner {address: voted-notifier}))) (unwrap-panic (get value (map-get? map-is-miner {address: voted-notifier})))) err-not-in-miner-map)
(asserts! (and (is-some (get value (map-get? map-is-miner {address: tx-sender}))) (unwrap-panic (get value (map-get? map-is-miner {address: tx-sender})))) err-no-vote-permission)
(asserts! (var-get notifier-vote-active) err-not-voting-period)
(asserts! ( < block-height (var-get notifier-vote-end-block)) err-not-voting-period)
(asserts! (is-none (get miner-voted (map-get? map-voted-update-notifier {miner-who-voted: tx-sender}))) err-already-voted)
(map-set map-voted-update-notifier {miner-who-voted : tx-sender} {miner-voted : voted-notifier})
( if (is-none ( get votes-number (map-get? map-votes-notifier {voted-notifier : voted-notifier})))
(map-set map-votes-notifier {voted-notifier : voted-notifier} {votes-number : u1})
(map-set map-votes-notifier {voted-notifier: voted-notifier} {votes-number: (+ (unwrap-panic (get votes-number (map-get? map-votes-notifier {voted-notifier: voted-notifier}))) u1)}))
(try!
(if (is-vote-accepted (+ (unwrap-panic (get votes-number (map-get? map-votes-notifier {voted-notifier: voted-notifier}))) u1) (var-get k))
(begin
(var-set notifier voted-notifier)
(var-set notifier-vote-end-block block-height)
(var-set notifier-vote-active false)
(end-vote-notifier))
(ok false)))
(ok true)))
;; ELECTION FUNCTIONS
(define-private (is-vote-accepted (votes-number uint) (k-local uint))
( if
(is-eq k-local u0) ;; k is 0 for n=1, n=2
( >= votes-number u1)
( >= votes-number k-local)))
(define-private (is-democratic-vote-accepted-notifier (votes-number uint) (k-local uint))
( if
(is-eq k-local u0) ;; k is 0 for n=1, n=2
( >= votes-number u1)
( >= votes-number ( / k-local u2))))