-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.py
208 lines (159 loc) · 6.9 KB
/
main.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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
from settings import filename, method_name, gas_consumed, analyze_all_blocks, start_block, is_free_mint, end_block, defined_price_each
import csv
def printLog(*args, **kwargs):
print(*args, **kwargs)
with open(f'./stats_dump/{filename}.txt', 'a') as file:
print(*args, **kwargs, file=file)
def format_time(seconds):
second_f = seconds % 60
min_f = seconds//60
hour_f = min_f//60
if hour_f > 0:
min_f -= hour_f * 60
if hour_f > 0:
return str(hour_f) + 'h' + str(min_f) + 'm' + str(second_f) + 's'
if min_f > 0:
return str(min_f) + 'm' + str(second_f) + 's'
return str(second_f) + 's'
def getCost(transaction_list):
info_list = []
for transaction in transaction_list:
# Note we are temporarily assuming that free mints only allow 1 per transaction
if is_free_mint:
info_list.append(float(transaction[header['TxnFee(ETH)']]))
else:
total_minted_local = round(
float(transaction[header['Value_IN(ETH)']])/price_each)
info_list.append(
float(transaction[header['TxnFee(ETH)']])/total_minted_local)
return info_list
def getStats(info_list):
printLog("Average", round(sum(info_list)/len(info_list), 5))
printLog("Median:", round(info_list[int(len(info_list)/2)], 5))
printLog("10th percentile", round(info_list[int(len(info_list)/10)], 5))
printLog("90th percentile", round(info_list[int(len(info_list)/10*9)], 5))
printLog("Min:", round(min(info_list), 5))
printLog("Max:", round(max(info_list), 5))
def gasToMintCost(gas):
return round(gas*gas_consumed/10**9 + price_each, 5)
def getGasStats(info_list):
avg = round(sum(info_list)/len(info_list)/gas_consumed*10**9, 5)
median = round(info_list[int(len(info_list)/2)]/gas_consumed*10**9, 5)
tenth = round(info_list[int(len(info_list)/10)]/gas_consumed*10**9, 5)
ninetyth = round(info_list[int(len(info_list)/10*9)]/gas_consumed*10**9, 5)
min_gas = round(min(info_list)/gas_consumed*10**9, 5)
max_gas = round(max(info_list)/gas_consumed*10**9, 5)
printLog("Successful tx:", len(info_list))
printLog("Average", avg, '/', gasToMintCost(avg))
printLog("Median:", median, '/', gasToMintCost(median))
printLog("10th percentile", tenth, '/', gasToMintCost(tenth))
printLog("90th percentile", ninetyth, '/', gasToMintCost(ninetyth))
printLog("Min:", min_gas, '/', gasToMintCost(min_gas))
printLog("Max:", max_gas, '/', gasToMintCost(max_gas))
header_list = ['Txhash', 'Blockno', 'UnixTimestamp', 'DateTime', 'From', 'To', 'ContractAddress',
'Value_IN(ETH)', 'Value_OUT(ETH)', 'CurrentValue @ $4122.28/Eth', 'TxnFee(ETH)',
'TxnFee(USD)', 'Historical $Price/Eth', 'Status', 'ErrCode', 'Method']
header = {k: v for v, k in enumerate(header_list)}
with open(f'./csv_exports/{filename}', 'r') as csvfile:
datareader = csv.reader(csvfile)
total_price = 0
successful_mint = []
failed_mint = []
price_each = 100
free_mint = 0
most_repeated_method = {}
# TODO: Get mint method based on most repeated statement
# Get all valid mints first
for row in datareader:
# Avoid initial header case
try:
block_no = int(row[header['Blockno']])
except:
continue
# Ignore certain blocks prior to certain mints
if block_no < start_block or block_no > end_block:
continue
if row[header['Method']] == method_name:
# Gets successful mints
if row[header['ErrCode']] == '':
# Ignore free mints to prevent 0 division issue
if float(row[header['Value_IN(ETH)']]) == 0:
free_mint += 1
# Determines the price of each mint by checking for lowest successful price that IS NOT 0
elif float(row[header['Value_IN(ETH)']]) <= price_each:
price_each = float(row[header['Value_IN(ETH)']])
successful_mint.append(row)
# Gets failed mints
else:
failed_mint.append(row)
# Changes price to 0 the mint was completely free
if is_free_mint:
price_each = 0
# Overwrites price_each if we define price in settings
if defined_price_each != -1:
price_each = defined_price_each
# Calculating gas loss from failed mint
gas_loss = 0
for mint in failed_mint:
gas_loss += float(mint[header['TxnFee(ETH)']])
# Calculate duration by taking first successful_mint - last
block_duration_blk = int(successful_mint[-1][header['Blockno']]) - \
int(successful_mint[0][header['Blockno']]) + 1
block_duration_seconds = int(successful_mint[-1][header['UnixTimestamp']]) - \
int(successful_mint[0][header['UnixTimestamp']])
printLog("Price each:", round(price_each, 3))
printLog("Total transactions:", len(successful_mint) + len(failed_mint))
printLog("Total successful transactions:", len(successful_mint))
printLog("Total failed transactions", len(failed_mint),
"/ Gas lost:", round(gas_loss, 2))
printLog("Total free mints:", free_mint)
printLog("Duration taken:", block_duration_blk,
"Blocks /", format_time(block_duration_seconds))
total_minted = free_mint
total_minted_local = 0
base_cost_list = []
gas_cost_list = []
block_dict = {}
printLog('-------------------------')
printLog('Successful mint analysis')
for mint in successful_mint:
if not is_free_mint:
# Ignore 0 value if detected
if float(mint[header['Value_IN(ETH)']]) == 0:
continue
total_minted_local = round(
float(mint[header['Value_IN(ETH)']])/price_each)
gas_cost_list.append(
float(mint[header['TxnFee(ETH)']])/total_minted_local)
base_cost_list.append(
float(mint[header['TxnFee(ETH)']])/total_minted_local + price_each)
else:
gas_cost_list.append(float(mint[header['TxnFee(ETH)']]))
base_cost_list.append(
float(mint[header['TxnFee(ETH)']]))
total_minted += total_minted_local
# Append based on block
if mint[header['Blockno']] not in block_dict:
block_dict[mint[header['Blockno']]] = [mint]
else:
block_dict[mint[header['Blockno']]].append(mint)
printLog("Total minted in public:", total_minted)
printLog('-------------\nCost analysis (Eth)')
getStats(base_cost_list)
printLog('---------------\nGas Analysis (Gwei)')
getGasStats(gas_cost_list)
printLog('--------------------\nBlock Analysis')
printLog("Total blocks:", len(block_dict))
if analyze_all_blocks == True:
for block in block_dict:
printLog(block)
getGasStats(getCost(block_dict[block]))
printLog('---------------')
else:
block_dict_list = list(block_dict)
printLog(block_dict_list[0])
getGasStats(getCost(block_dict[block_dict_list[0]]))
printLog('---------------')
printLog(block_dict_list[-1])
getGasStats(getCost(block_dict[block_dict_list[-1]]))
printLog('---------------')