Skip to content

Instantly share code, notes, and snippets.

@mquandalle
Last active August 15, 2022 13:31
Show Gist options
  • Save mquandalle/f8d3fbcc5923495f0f3d to your computer and use it in GitHub Desktop.
Save mquandalle/f8d3fbcc5923495f0f3d to your computer and use it in GitHub Desktop.
Karma police: a reputation system on ethereum

Karma police: a simple reputation system on top of ethereum

Tired of the alcoins mania? Here is a coin that you cannot exhange or lose. It aims to be a reputation system. Every n=42 days m=1000000 karma units are issued. So it's a disinflationary unit.

Users of this system can votes ("+1") for others if they do a great contribution. A user with 1% of the total amount of karma will "distribute" 1% of the new m units. These new karma units are equally distributed between all users that have received a vote from him.

Persistent storage usage

Global informations

[0] ; total amount of karma
[1] ; number of checkouts
[2] ; last checkout timestamp

Karma units before checkouts

[-1] ; Total amount of karma units before checkout 1
[-2] ; Total amount of karma units before checkout 2
...

Votes

@location = addr * 10000 * 10000;
[location - 1] ; karma of addr
[location - 2] ; lastCheckoutIndex

[location + checkoutIndex * 10000 - 1] ; personnal amount of karma units before checkoutIndex
[location + checkoutIndex * 10000]     ; number of votes
[location + checkoutIndex * 10000 + 1] ; vote n°1
[location + checkoutIndex * 10000 + 2] ; vote n°2
{
[2] (timestamp)
}
{
; Contract parameters
[daysBetweenCheckouts] 42
[newKarmaUnitsByCheckout] 1000000
; Global infos
[globalAmountOfKarma] @@0
[lastCheckoutIndex] @@1
[lastCheckoutTimestamp] @@2
; If needed, update last checkout informations
(when (> (+ @lastCheckoutTimestamp (* @daysBetweenCheckouts 24 60 60)) (timestamp)) {
[lastCheckoutIndex] (+ @lastCheckoutIndex 1)
[lastCheckoutTimestamp] (timestamp)
[[1]] @lastCheckoutIndex
[[2]] @lastCheckoutTimestamp
[[(- @lastCheckoutIndex)]] @globalAmountOfKarma})
; Caller user infos
[location] (* (caller) 10000 10000)
[myKarma] @@(- @location 1)
[lastCheckoutDistributed] @@(- @location 2)
; If this user hasn't call this contract since the last checkout, we need to distribute new karma units earned in previous periods
(for [checkoutIndex] (+ @lastCheckoutDistributed 1) (<= @checkoutIndex @lastCheckoutIndex) [checkoutIndex] (+ @checkoutIndex 1) {
[checkoutLoc] (+ @location (* 10000 @checkoutIndex))
[nbVotes] @@@checkoutLoc
[karmaBeforeCheckout] @@(- @checkoutLoc 1)
[totalKarmaBeforeCheckout] @@(- @checkoutIndex)
[newUnitsByVote] (+ (/ (* @karmaBeforeCheckout @newKarmaUnitsByCheckout) @totalKarmaBeforeCheckout @nbVotes) 1)
(for () (< @m @nbVotes) [m] (+ @m 1) {
[receiverAddress] @@(+ @location (* 10000 @checkoutIndex) @m)
[receiverLoc] (* @receiverAddress 10000 10000)
[receiverCurrentKarma] @@(- @receiverLoc 1)
[[(- (+ @receiverLoc (* @checkoutIndex 10000)) 1)]] @receiverCurrentKarma ; Backup current karma
[[(- @receiverLoc 1)]] (+ @receiverCurrentKarma @newUnitsByVote)
[[0]] (+ @globalAmountOfKarma @newUnitsByVote)})}) ; Increment receiver karma
; And now it's time to register the new votes for the current period!
[votesLoc] (+ @location (* 10000 @lastCheckoutIndex))
[nbVotes] @@@votesLoc
[nbNewVotes] (/ (calldatasize) 32)
[[@votesLoc]] (+ @nbVotes @nbNewVotes)
(for () (< @i @nbNewVotes) [i] (+ @i 1)
[[(+ @votesLoc @nbVotes @i 1)]] (calldataload (* @i 32)))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment