def _parseStateDiff(account_state, type): state_from = None state_to = None state_diff = None assert len(account_state) == 1 if isinstance(account_state, dict): key = list(account_state) if key[0] == '*': if type == 'code': state_from = account_state['*']['from'] state_to = account_state['*']['to'] else: state_diff = hex_to_integer(account_state['*']['to']) - \ hex_to_integer(account_state['*']['from']) elif key[0] == '+': if type == 'code': state_to = account_state['+'] else: state_diff = hex_to_integer(account_state['+']) elif key[0] == '-': if type == 'code': state_from = account_state['-'] else: state_diff = -1 * hex_to_integer(account_state['-']) else: raise ValueError('Unknown key {} in account state'.format(key)) elif account_state == '=': logger.debug('No change in type'.format(type)) else: raise ValueError('Unknown account state {}'.format(account_state)) return state_from, state_to, state_diff
def add_uncle(cls, uncle_data, block_number, iso_timestamp): """ Creates a new block object from data received from JSON-RPC call eth_getUncleByBlockNumberAndIndex. :param dict uncle_data: uncle data received from JSON RPC call :param int block_number: block number where this uncle was included :param datetime iso_timestamp: timestamp when the block was mined """ logger.debug('{}'.format(uncle_data['gasUsed'])) uncle = cls( uncle_hash=uncle_data['hash'], uncle_blocknumber=hex_to_integer( uncle_data['number']), # 'uncle_blocknumber' parent_hash=uncle_data['parentHash'], # parent_hash difficulty=hex_to_integer(uncle_data['difficulty']), # 'difficulty current_blocknumber=block_number, # current_blocknumber gas_used=hex_to_integer(uncle_data['gasUsed']), # gas_used miner=to_checksum_address(uncle_data['miner']), # miner timestamp=iso_timestamp, sha3uncles=uncle_data['sha3Uncles'], # SHA3uncles extra_data=uncle_data['extraData'], # extra_data gas_limit=hex_to_integer(uncle_data['gasLimit'])) return uncle
def get_storage_at_block(cls, current_session, block_number): """ Gives the storage values at requested block :param int block_number: Block number of desired storage, always required since it is called from method `State.get_state_at_block` """ row_number_column = func.row_number().over( partition_by=[StorageDiff.address, StorageDiff.position], order_by=[StorageDiff.block_number.desc(), StorageDiff.transaction_index.desc()])\ .label('row_number') query = current_session.db_session.query(StorageDiff.address, StorageDiff.position, StorageDiff.storage_to.label('storage')) query = query.add_column(row_number_column) query = query.filter( and_( StorageDiff.block_number <= block_number, StorageDiff.storage_to != '0x0000000000000000000000000000000000000000000000000000000000000000')) query = query.from_self().filter(row_number_column == 1) for row in query: if row.storage is not None: if hex_to_integer(row.storage) != 0: storage = cls.add_storage(address=row.address, position=row.position, storage=row.storage) else: # not adding storage positions where value is 0, since parity discards these positions during export logger.debug('address: {}, position {}, storage: {} is zero'.format(row.address, row.position, row.storage)) current_session.db_session.add(storage) else: logger.debug('address: {}, position {}, storage: {} is none'.format(row.address, row.position, row.storage))
def match_state_dump_to_state_table(block_number): current_session = get_current_session() with open('tests/fixtures/balance/balance_{}.json'.format(block_number)) as data_file: data = json.loads(data_file.read()) state = data['state'] with current_session.db_session_scope(): for address in state: state_table_row = current_session.db_session.query(State).\ filter_by(address=to_checksum_address(address)).first() assert state_table_row.balance == hex_to_integer(state[address]['balance']) assert state_table_row.nonce == hex_to_integer(state[address]['nonce']) if 'code' in state[address].keys(): assert state_table_row.code == "0x"+state[address]['code'] if state_table_row.storage is not None: for storage in state_table_row.storage: storage.storage = state[address]['storage'][storage.position]
def main(): with open('balance/balance_0.json') as data_file: data = json.loads(data_file.read()) state = data['state'] with open('dict.csv', 'w') as csv_file: writer = csv.writer(csv_file) for address in state: writer.writerow( [address, hex_to_integer(state[address]['balance'])])
def test_trace_call(self, web3, math_contract, math_contract_address): coinbase = web3.eth.coinbase txn_params = math_contract._prepare_transaction( fn_name='add', fn_args=(7, 11), transaction={ 'from': coinbase, 'to': math_contract_address }, ) trace = web3.parity.traceCall(txn_params) assert trace['stateDiff'] is None assert trace['vmTrace'] is None result = hex_to_integer(trace['output']) assert result == 18
def add_trace(cls, dict_trace, transaction_hash, transaction_index, block_number, timestamp): """ Creates a new trace object from data received from JSON-RPC call trace_transaction. :param dict dict_trace: trace data received from the JSON RPC callable :param int timestamp: timestamp of the block where this trace was included :param int block_number: block number of the block where this trance was included """ logger.debug(dict_trace['action']) trace = cls(transaction_hash=transaction_hash, block_number=block_number, trace_address=dict_trace['traceAddress'], subtraces=dict_trace['subtraces'], transaction_index=transaction_index, trace_type=dict_trace['type'], sender='', receiver='', start_gas=None, value=None, input_data='', gas_used=None, output='', contract_address='', error='') action = dict_trace['action'] if trace.trace_type == 'call': # parsing action trace.sender = to_checksum_address(action['from']) trace.receiver = to_checksum_address(action['to']) trace.start_gas = hex_to_integer(action['gas']) trace.value = hex_to_integer(action['value']) trace.input_data = action['input'] # parsing result if 'result' in list(dict_trace.keys()): result = dict_trace['result'] trace.gas_used = hex_to_integer(result['gasUsed']) trace.output = result['output'] else: trace.error = dict_trace['error'] elif trace.trace_type == 'create': logger.debug('Type {}, action {}'.format(dict_trace['type'], action)) # parsing action trace.start_gas = hex_to_integer(action['gas']) trace.value = hex_to_integer(action['value']) trace.input_data = action['init'] # parsing result if 'result' in list(dict_trace.keys()): result = dict_trace['result'] trace.gas_used = hex_to_integer(result['gasUsed']) trace.output = result['code'] trace.contract_address = to_checksum_address(result['address']) else: trace.error = dict_trace['error'] elif trace.trace_type == 'suicide': logger.debug('Type {}, action {}'.format(dict_trace['type'], action)) # parsing action trace.sender = to_checksum_address(action['address']) trace.receiver = to_checksum_address(action['refundAddress']) trace.value = hex_to_integer(action['balance']) # parsing result logger.debug('Type encountered {}'.format(dict_trace['type'])) return trace