forked from ethereum/pyethsaletool
-
Notifications
You must be signed in to change notification settings - Fork 0
/
genesis_block_generator.py
141 lines (124 loc) · 4.34 KB
/
genesis_block_generator.py
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
import bitcoin as b
import sys
import json
import os
# Timestamp of sale start
start = 1406066400
# Initial sale rate
initial_rate = 2000
# Initial sale rate duration
initial_period = 14 * 86400
# step size for declining rate phase
rate_decline = 30
# Length of step
rate_period = 86400
# Number of declining periods
rate_periods = 22
# Final rate
final_rate = 1337
# Period during which final rate is effective
final_period = 6 * 86400 + 3600 # 1h of slack
# Accept post-sale purchases?
post_rate = 0
exodus = '36PrZ1KHYMpqSyAQXSG8VwbUiq2EogxLo2'
minimum = 1000000
maximum = 150000000000
caches = {}
try:
os.mkdir('caches')
except:
pass
# Cache methods that get networking data. Important since this script takes
# a very long time, and will almost certainly be interrupted multiple times
# while in progress
def cache_method_factory(method, filename):
def new_method(arg):
if filename not in caches:
try:
caches[filename] = json.load(open(filename, 'r'))
except:
caches[filename] = {}
c = caches[filename]
if str(arg) not in c:
c[str(arg)] = method(arg)
json.dump(c, open(filename, 'w'))
return c[str(arg)]
return new_method
# Cached versions of the BCI methods that we need
get_block_header_data = cache_method_factory(b.get_block_header_data,
'caches/blockheaders.json')
fetchtx = cache_method_factory(b.fetchtx, 'caches/fetchtx.json')
history = cache_method_factory(b.history, 'caches/history.json')
# Get a dictionary of the transactions and block heights from the history
def get_txs_and_heights(outs):
txs = {}
heights = {}
for o in outs:
if o['output'][65:] == '0':
h = o['output'][:64]
txs[h] = fetchtx(h)
heights[h] = o['block_height']
# print txs[h]
if len(txs) % 50 == 0:
sys.stderr.write('Processed transactions: %d\n' % len(txs))
return {"txs": txs, "heights": heights}
# Produce a json list of purchases
def list_purchases(obj):
txs, heights = obj['txs'], obj['heights']
o = []
for h in txs:
txhex = str(txs[h])
# print txhex
txouts = b.deserialize(txhex)['outs']
if len(txouts) >= 2 and txouts[0]['value'] >= minimum - 30000:
addr = b.script_to_address(txouts[0]['script'])
if addr == exodus:
v = txouts[0]['value'] + 30000
ht = heights[h]
# We care about the timestamp of the previous
# confirmed block before a transaction
t = get_block_header_data(ht - 1)['timestamp']
o.append({
"tx": h,
"addr": b.b58check_to_hex(b.script_to_address(
txouts[1]['script'])),
"value": v,
"time": t
})
if len(o) % 50 == 0:
sys.stderr.write('Gathered outputs: %d\n' % len(o))
return o
# Compute ether value from BTC value
def evaluate_purchases(purchases):
o = {}
for p in purchases:
if p["time"] < start + initial_period:
rate = initial_rate
elif p["time"] < start + initial_period + rate_period * rate_periods:
pid = (p["time"] - (start + initial_period)) // rate_period + 1
rate = initial_rate - rate_decline * pid
elif p["time"] < start + initial_period + rate_period * \
rate_periods + final_period:
rate = final_rate
else:
rate = post_rate
# Round to the nearest finney (nearest ether would be // 10**8)
purchase_amount = (p["value"] * rate // 10**5) * 10**15
if p["addr"] in o:
current_balance = o[p["addr"]]["wei"]
purchase_amount = int(current_balance) + purchase_amount
o[p["addr"]] = {
"wei": str(purchase_amount)
}
return o
def evaluate():
outs = history(exodus)
sys.stderr.write('Gathered history: %d\n' % len(outs))
th = get_txs_and_heights(outs)
sys.stderr.write('Gathered txs and heights\n')
p = list_purchases(th)
sys.stderr.write('Listed purchases\n')
o = evaluate_purchases(p)
return o
if __name__ == '__main__':
print json.dumps(evaluate(), indent=4)