Add the first code to build transaction traces from the storage state at STOP instruction and a combination strategy to build felxibly large trace chain combinations. Starting from the trace of a constructor and using the traces of the external and public functions of a contract. All possible programmstates to a certain depth can be reached.

pull/310/head
Konrad Weiss 7 years ago
parent c3131a579d
commit 0f458e7541
  1. 22
      mythril/analysis/modules/build_traces.py
  2. 27
      mythril/solidnotary.py
  3. 54
      mythril/solidnotary/transactiontrace.py

@ -0,0 +1,22 @@
from mythril.analysis.report import Issue
import logging
'''
Build execution traces from the statespace
'''
def print_obj(obj):
print()
print(obj)
# print(dir(obj))
print()
def execute(statespace):
logging.debug("Executing module: Transaction End")
traces = []
return []

@ -0,0 +1,27 @@
import logging
from mythril.solidnotary.transactiontrace import TransactionTrace
class SolidNotary:
def __init__(self):
# Todo Parse Annotations and store them in an additional structure
# Todo receive a list of files or a file, these are modified for the analysis
pass
def notarize(self):
# Todo Instantiate an instance of Mythril, analyze and print the result
# Todo Find how they are storing results
pass
def get_transaction_traces(statespace):
logging.debug("Executing module: Transaction End")
traces = []
for k in statespace.nodes:
node = statespace.nodes[k]
for state in node.states:
instruction = state.get_current_instruction()
if instruction['opcode'] == "STOP":
traces.append(TransactionTrace(state.environment.active_account.storage))
return traces

@ -0,0 +1,54 @@
class TransactionTrace:
def __init__(self, storage):
self.storage = storage
# Todo Identifiy addional trace information such as blocknumber and more
"""
Applies the new trace tt on a possibly even changed trace self.
"""
def apply_trace(self, tt):
if tt is None:
return self
# Todo implement application of a trace on a existing trace.
return None
def apply_traces_parallel(self, traces):
combined_traces = []
for trace in traces:
combined_traces.append(self.apply_trace(trace))
return combined_traces
def apply_exact_trace_levels(self, traces, depth):
# Todo maybe some faster trace build not building one level at a time to e.g.
# Todo reach level 17 but build 2, then 4, then 8 and then 16 then 17
trace_lvl_n = [self]
for i in range(depth):
trace_lvl_np1 = []
for trace in trace_lvl_n:
trace_lvl_np1.append(trace.apply_traces_parallel(traces))
if deep_equals(trace_lvl_np1, trace_lvl_n): # Fixpoint detected, function needs to ignore lists, dicts and objects.
return trace_lvl_n
trace_lvl_n = trace_lvl_np1
return trace_lvl_n
def apply_up_to_trace_levels(self, traces, depth):
traces_up_to = [[self]] # elements are trace_levels
for i in range(depth):
trace_lvl_np1 = []
for trace in traces_up_to[-1]:
trace_lvl_np1.append(trace.apply_traces_parallel(traces))
for trace_lvl_i in traces_up_to:
# the following might be faster to check when using a content representing hash
if deep_equals(trace_lvl_np1, trace_lvl_i): # cycle in the traces of trace chains detected: levels
# while repeat themselves, function needs to ignore lists, dicts and objects.
return traces_up_to
traces_up_to.append(trace_lvl_np1)
return traces_up_to
"""
Either do only deep checing here and use the proper trace or storage_slot reduction in the apply function. Or do
both here.
"""
def deep_equals(trace_lvl1, trace_lvl2):
pass
Loading…
Cancel
Save