Last active
August 30, 2016 20:33
-
-
Save AlexeyAkhunov/2014fae5802d78a48cb73666b8975b72 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# In order for this to work, you need to install parity (of version at least 1.3.0) | |
# and run it like this: | |
# | |
# parity --tracing on --pruning=archive | |
# | |
# Allow it to sync to at least the hard fork block before running this script | |
# | |
import httplib | |
import json | |
import sys | |
import os.path | |
filename = 'my_extrabalance.json' | |
THE_DAO_ADDRESS = 'bb9bc244d798123fde783fcc1c72d3bb8c189413' | |
START_BLOCK = 1429038 | |
END_BLOCK = 1599205 | |
DAO_CREATED_TOKEN_TOPIC = '0xdbccb92686efceafb9bb7e0394df7f58f71b954061b81afb57109bf247d3d75a' | |
''' | |
function divisor() constant returns (uint divisor) { | |
// The number of (base unit) tokens per wei is calculated | |
// as `msg.value` * 20 / `divisor` | |
// The fueling period starts with a 1:1 ratio | |
if (closingTime - 2 weeks > now) { | |
return 20; | |
// Followed by 10 days with a daily creation rate increase of 5% | |
} else if (closingTime - 4 days > now) { | |
return (20 + (now - (closingTime - 2 weeks)) / (1 days)); | |
// The last 4 days there is a constant creation rate ratio of 1:1.5 | |
} else { | |
return 30; | |
} | |
''' | |
# Open connection to parity JSON RPC | |
http = httplib.HTTPConnection('localhost:8545') | |
def get_created_tokens(connection): | |
params = [{"address": "0x" + THE_DAO_ADDRESS, | |
"fromBlock": str(START_BLOCK), | |
"toBlock": str(END_BLOCK), | |
"topics": [DAO_CREATED_TOKEN_TOPIC] | |
}] | |
http.request( | |
method='POST', | |
url='', | |
body=json.dumps({"jsonrpc": "2.0", "method": "eth_getLogs", "params": params, "id": 0}), | |
headers={'Content-Type': 'application/json'}) | |
response = http.getresponse() | |
if response.status != httplib.OK: | |
print 'Could not read CreatedToken events', response.status, response.reason | |
sys.exit(0) | |
return json.load(response) | |
def get_dao_closing_time(connection): | |
params = [{"to": "0x" + THE_DAO_ADDRESS, "data": "0x4b6753bc"}] # 4b6753bc is prefix of closingTime() | |
http.request( | |
method='POST', | |
url='', | |
body=json.dumps({"jsonrpc": "2.0", "method": "eth_call", "params": params, "id": 0}), | |
headers={'Content-Type': 'application/json'}) | |
response = http.getresponse() | |
if response.status != httplib.OK: | |
print 'Could not read childDAO closing time', response.status, response.reason | |
sys.exit(0) | |
return long(json.load(response)['result'][2:], 16) | |
def get_block_timestamp(connection, block_number): | |
params = [str(block_number), "false"] | |
http.request( | |
method='POST', | |
url='', | |
body=json.dumps({"jsonrpc": "2.0", "method": "eth_getBlockByNumber", "params": params, "id": 0}), | |
headers={'Content-Type': 'application/json'}) | |
response = http.getresponse() | |
if response.status != httplib.OK: | |
print 'Could not read block information', response.status, response.reason | |
sys.exit(0) | |
return long(json.load(response)['result']['timestamp'][2:], 16) | |
DAO_CLOSING_TIME = get_dao_closing_time(http) | |
ONE_DAYS = 3600*24 | |
FOUR_DAYS = 4*ONE_DAYS | |
TWO_WEEKS = 14*ONE_DAYS | |
print 'Reading block timestamps from blocks from %d to %d...' % (START_BLOCK, END_BLOCK) | |
block_timestamps = {} | |
for b in xrange(START_BLOCK, END_BLOCK+1): | |
block_timestamps[b] = get_block_timestamp(http, b) | |
if b % 10000 == 0: | |
print b | |
print 'Reading DAO CreatedToken events via Parity JSON RPC...' | |
created_tokens = get_created_tokens(http) | |
http.close() | |
class Extra: | |
""" Represent part of the extraBalanced with the owner """ | |
def __init__(self, address_, wei_): | |
self.address = address_ | |
self.wei = wei_ | |
extras = [] | |
for r in created_tokens['result']: | |
owner = r['topics'][1][26:] | |
tokens = long(r['data'][2:], 16) | |
timestamp = block_timestamps[int(r['blockNumber'][2:], 16)] | |
if DAO_CLOSING_TIME - TWO_WEEKS > timestamp: | |
divisor = 20; | |
elif DAO_CLOSING_TIME - FOUR_DAYS > timestamp: | |
divisor = (20 + (timestamp - (DAO_CLOSING_TIME - TWO_WEEKS)) / (ONE_DAYS)); | |
else: | |
divisor = 30 | |
msg_value = tokens * divisor / 20 | |
extra = msg_value - tokens | |
if extra > 0: | |
extras.append(Extra(address_=owner, wei_=extra)) | |
from itertools import groupby | |
# Aggregate extras by address | |
extras = [Extra(address, sum(map(lambda e: e.wei, group))) for address, group in groupby(sorted(extras,key=lambda e: e.address), lambda e: e.address)] | |
with open(filename, 'w') as f: | |
json.dump([['0x' + e.address, str(e.wei)] for e in extras], f) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment