forked from 621625/bitcoinmeetups.github.com
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathschellingcoin
More file actions
114 lines (103 loc) · 3.42 KB
/
schellingcoin
File metadata and controls
114 lines (103 loc) · 3.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#How could a corresponding JavaScript file to this Serpent contract look?
# SchellingCoin implementation
#
# Stored variables:
#
# 0: last_processed_block
# 1: number of hashes submitted
# 2: value
# 3: quicksort_pairs address
#
# 2^160 + 3x: hash
# 2^160 + 3x + 1: deposit
# 2^160 + 3x + 2: address
# 2^170 + x: value
#
# Transaction types:
#
# [1, sha3([address, value])] -> id: submit hash (only works when block number mod 100 < 50)
#
# [2, id, value]: submit answer (only works when block number mod 100 >= 50)
#
# [3]: balance query
#
# [4]: value query
#
# Parameters:
#
# Epoch length: 100 blocks
# Target savings depletion rate: 0.1% per epoch
init:
contract.storage[0] = block.number
contract.storage[3] = create('quicksort_pairs.se')
code:
HASHES = 2^160
VALUES = 2^170
if block.number / 100 > contract.storage[0] / 100:
# Sort all hashes
N = contract.storage[1]
o = array(N * 2)
i = 0
j = 0
while i < N:
if contract.storage[VALUES + i]:
o[j] = contract.storage[VALUES + i]
o[j + 1] = i
j += 2
i += 1
values = call(contract.storage[3], o, j, 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] = contract.storage[base_index + 1]
addresses[i] = contract.storage[base_index + 2]
if contract.storage[VALUES + values[i * 2 + 1]]:
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:
contract.storage[2] = contract.storage[VALUES + i]
halfway_passed = 1
contract.storage[VALUES + i] = 0
running_deposit_sum = new_deposit_sum
i += 1
contract.storage[0] = block.number
contract.storage[1] = 0
# Hash submission
if msg.data[0] == 1:
if block.number % 100 < 50:
cur = contract.storage[1]
pos = HASHES + cur * 3
contract.storage[pos] = msg.data[1]
contract.storage[pos + 1] = msg.value
contract.storage[pos + 2] = msg.sender
contract.storage[1] = cur + 1
return(cur)
# Value submission
elif msg.data[0] == 2:
if sha3([msg.sender, msg.data[2]], 2) == contract.storage[HASHES + msg.data[1] * 3]:
contract.storage[VALUES + msg.data[1]] = msg.data[2]
return(1)
# Balance request
elif msg.data[0] == 3:
return(contract.balance)
# Value request
else:
return(contract.storage[2])