def json_dict_to_trace(self, json_dict): trace = EthTrace() trace.block_number = json_dict.get('blockNumber') trace.transaction_hash = json_dict.get('transactionHash') trace.transaction_index = json_dict.get('transactionPosition') trace.subtraces = json_dict.get('subtraces') trace.trace_address = json_dict.get('traceAddress', []) error = json_dict.get('error') if error: trace.error = error action = json_dict.get('action') if action is None: action = {} result = json_dict.get('result') if result is None: result = {} trace_type = json_dict.get('type') trace.trace_type = trace_type # common fields in call/create if trace_type in ('call', 'create'): trace.from_address = to_normalized_address(action.get('from')) trace.value = hex_to_dec(action.get('value')) trace.gas = hex_to_dec(action.get('gas')) trace.gas_used = hex_to_dec(result.get('gasUsed')) # process different trace types if trace_type == 'call': trace.call_type = action.get('callType') trace.to_address = to_normalized_address(action.get('to')) trace.input = action.get('input') trace.output = result.get('output') elif trace_type == 'create': trace.to_address = result.get('address') trace.input = action.get('init') trace.output = result.get('code') elif trace_type == 'suicide': trace.from_address = to_normalized_address(action.get('address')) trace.to_address = to_normalized_address( action.get('refundAddress')) trace.value = hex_to_dec(action.get('balance')) elif trace_type == 'reward': trace.to_address = to_normalized_address(action.get('author')) trace.value = hex_to_dec(action.get('value')) trace.reward_type = action.get('rewardType') return trace
def json_dict_to_receipt_log(self, json_dict): receipt_log = EthReceiptLog() receipt_log.log_index = hex_to_dec(json_dict.get('logIndex')) receipt_log.transaction_hash = json_dict.get('transactionHash') receipt_log.transaction_index = hex_to_dec( json_dict.get('transactionIndex')) receipt_log.block_hash = json_dict.get('blockHash') receipt_log.block_number = hex_to_dec(json_dict.get('blockNumber')) receipt_log.address = json_dict.get('address') receipt_log.data = json_dict.get('data') receipt_log.topics = json_dict.get('topics') return receipt_log
def extract_transfer_from_log(self, receipt_log): topics = receipt_log.topics if topics is None or len(topics) < 1: logger.warning("Topics are empty in log {} of transaction {}".format(receipt_log.log_index, receipt_log.transaction_hash)) return None if topics[0] == TRANSFER_EVENT_TOPIC: # Handle unindexed event fields topics_with_data = topics + split_to_words(receipt_log.data) # if the number of topics and fields in data part != 4, then it's a weird event if len(topics_with_data) != 4: logger.warning("The number of topics and data parts is not equal to 4 in log {} of transaction {}" .format(receipt_log.log_index, receipt_log.transaction_hash)) return None token_transfer = EthTokenTransfer() token_transfer.token_address = to_normalized_address(receipt_log.address) token_transfer.from_address = word_to_address(topics_with_data[1]) token_transfer.to_address = word_to_address(topics_with_data[2]) token_transfer.value = hex_to_dec(topics_with_data[3]) token_transfer.transaction_hash = receipt_log.transaction_hash token_transfer.log_index = receipt_log.log_index token_transfer.block_number = receipt_log.block_number return token_transfer return None
def _iterate_transaction_trace(self, block_number, tx_index, tx_trace, trace_address=[]): trace = EthTrace() trace.block_number = block_number trace.transaction_index = tx_index trace.from_address = to_normalized_address(tx_trace.get('from')) trace.to_address = to_normalized_address(tx_trace.get('to')) trace.input = tx_trace.get('input') trace.output = tx_trace.get('output') trace.value = hex_to_dec(tx_trace.get('value')) trace.gas = hex_to_dec(tx_trace.get('gas')) trace.gas_used = hex_to_dec(tx_trace.get('gasUsed')) trace.error = tx_trace.get('error') # lowercase for compatibility with parity traces trace.trace_type = tx_trace.get('type').lower() if trace.trace_type == 'selfdestruct': # rename to suicide for compatibility with parity traces trace.trace_type = 'suicide' elif trace.trace_type in ('call', 'callcode', 'delegatecall', 'staticcall'): trace.call_type = trace.trace_type trace.trace_type = 'call' result = [trace] calls = tx_trace.get('calls', []) trace.subtraces = len(calls) trace.trace_address = trace_address for call_index, call_trace in enumerate(calls): result.extend( self._iterate_transaction_trace(block_number, tx_index, call_trace, trace_address + [call_index])) return result
def json_dict_to_block(self, json_dict): block = EthBlock() block.number = hex_to_dec(json_dict.get('number')) block.hash = json_dict.get('hash') block.parent_hash = json_dict.get('parentHash') block.nonce = json_dict.get('nonce') block.sha3_uncles = json_dict.get('sha3Uncles') block.logs_bloom = json_dict.get('logsBloom') block.transactions_root = json_dict.get('transactionsRoot') block.state_root = json_dict.get('stateRoot') block.receipts_root = json_dict.get('receiptsRoot') block.miner = to_normalized_address(json_dict.get('miner')) block.difficulty = hex_to_dec(json_dict.get('difficulty')) block.total_difficulty = hex_to_dec(json_dict.get('totalDifficulty')) block.size = hex_to_dec(json_dict.get('size')) block.extra_data = json_dict.get('extraData') block.gas_limit = hex_to_dec(json_dict.get('gasLimit')) block.gas_used = hex_to_dec(json_dict.get('gasUsed')) block.timestamp = hex_to_dec(json_dict.get('timestamp')) if 'transactions' in json_dict: block.transactions = [ self.transaction_mapper.json_dict_to_transaction(tx, block_timestamp=block.timestamp) for tx in json_dict['transactions'] if isinstance(tx, dict) ] block.transaction_count = len(json_dict['transactions']) return block
def json_dict_to_receipt(self, json_dict): receipt = EthReceipt() receipt.transaction_hash = json_dict.get('transactionHash') receipt.transaction_index = hex_to_dec(json_dict.get('transactionIndex')) receipt.block_hash = json_dict.get('blockHash') receipt.block_number = hex_to_dec(json_dict.get('blockNumber')) receipt.cumulative_gas_used = hex_to_dec(json_dict.get('cumulativeGasUsed')) receipt.gas_used = hex_to_dec(json_dict.get('gasUsed')) receipt.contract_address = to_normalized_address(json_dict.get('contractAddress')) receipt.root = json_dict.get('root') receipt.status = hex_to_dec(json_dict.get('status')) if 'logs' in json_dict: receipt.logs = [ self.receipt_log_mapper.json_dict_to_receipt_log(log) for log in json_dict['logs'] ] return receipt
def json_dict_to_transaction(self, json_dict, **kwargs): transaction = EthTransaction() transaction.hash = json_dict.get('hash') transaction.nonce = hex_to_dec(json_dict.get('nonce')) transaction.block_hash = json_dict.get('blockHash') transaction.block_number = hex_to_dec(json_dict.get('blockNumber')) transaction.block_timestamp = kwargs.get('block_timestamp') transaction.transaction_index = hex_to_dec(json_dict.get('transactionIndex')) transaction.from_address = to_normalized_address(json_dict.get('from')) transaction.to_address = to_normalized_address(json_dict.get('to')) transaction.value = hex_to_dec(json_dict.get('value')) transaction.gas = hex_to_dec(json_dict.get('gas')) transaction.gas_price = hex_to_dec(json_dict.get('gasPrice')) transaction.input = json_dict.get('input') return transaction