diff options
Diffstat (limited to 'Godeps/_workspace/src/github.com/ethereum/serpent-go/serpent/examples/schellingcoin/schellingcoin.se')
-rw-r--r-- | Godeps/_workspace/src/github.com/ethereum/serpent-go/serpent/examples/schellingcoin/schellingcoin.se | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/Godeps/_workspace/src/github.com/ethereum/serpent-go/serpent/examples/schellingcoin/schellingcoin.se b/Godeps/_workspace/src/github.com/ethereum/serpent-go/serpent/examples/schellingcoin/schellingcoin.se new file mode 100644 index 000000000..a7d7da9c5 --- /dev/null +++ b/Godeps/_workspace/src/github.com/ethereum/serpent-go/serpent/examples/schellingcoin/schellingcoin.se @@ -0,0 +1,94 @@ +# SchellingCoin implementation +# +# Epoch length: 100 blocks +# Target savings depletion rate: 0.1% per epoch + +data epoch +data hashes_submitted +data output +data quicksort_pairs +data accounts[2^160] +data submissions[2^80](hash, deposit, address, value) +extern any: [call] + + +def init(): + self.epoch = block.number / 100 + self.quicksort_pairs = create('quicksort_pairs.se') + +def any(): + if block.number / 100 > epoch: + # Sort all values submitted + N = self.hashes_submitted + o = array(N * 2) + i = 0 + j = 0 + while i < N: + v = self.submissions[i].value + if v: + o[j] = v + o[j + 1] = i + j += 2 + i += 1 + values = self.quicksort_pairs.call(data=o, datasz=j, outsz=j) + + # Calculate total deposit, refund non-submitters and + # cleanup + + deposits = array(j / 2) + addresses = array(j / 2) + + i = 0 + total_deposit = 0 + while i < j / 2: + base_index = HASHES + values[i * 2 + 1] * 3 + deposits[i] = self.submissions[i].deposit + addresses[i] = self.submissions[i].address + if self.submissions[values[i * 2 + 1]].value: + total_deposit += deposits[i] + else: + send(addresses[i], deposits[i] * 999 / 1000) + i += 1 + + inverse_profit_ratio = total_deposit / (contract.balance / 1000) + 1 + + # Reward everyone + i = 0 + running_deposit_sum = 0 + halfway_passed = 0 + while i < j / 2: + new_deposit_sum = running_deposit_sum + deposits[i] + if new_deposit_sum > total_deposit / 4 and running_deposit_sum < total_deposit * 3 / 4: + send(addresses[i], deposits[i] + deposits[i] / inverse_profit_ratio * 2) + else: + send(addresses[i], deposits[i] - deposits[i] / inverse_profit_ratio) + + if not halfway_passed and new_deposit_sum > total_deposit / 2: + self.output = self.submissions[i].value + halfway_passed = 1 + self.submissions[i].value = 0 + running_deposit_sum = new_deposit_sum + i += 1 + self.epoch = block.number / 100 + self.hashes_submitted = 0 + +def submit_hash(h): + if block.number % 100 < 50: + cur = self.hashes_submitted + pos = HASHES + cur * 3 + self.submissions[cur].hash = h + self.submissions[cur].deposit = msg.value + self.submissions[cur].address = msg.sender + self.hashes_submitted = cur + 1 + return(cur) + +def submit_value(index, v): + if sha3([msg.sender, v], 2) == self.submissions[index].hash: + self.submissions[index].value = v + return(1) + +def request_balance(): + return(contract.balance) + +def request_output(): + return(self.output) |