Beispiel #1
0
def word_to_address(param):
    if param is None:
        return None
    elif len(param) >= 40:
        return to_normalized_address('0x' + param[-40:])
    else:
        return to_normalized_address(param)
Beispiel #2
0
    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
Beispiel #3
0
 def json_dict_to_transaction(self, json_dict):
     transaction = EthTransaction()
     transaction.hash = json_dict.get('hash', None)
     transaction.nonce = hex_to_dec(json_dict.get('nonce', None))
     transaction.block_hash = json_dict.get('blockHash', None)
     transaction.block_number = hex_to_dec(json_dict.get('blockNumber', None))
     transaction.index = hex_to_dec(json_dict.get('transactionIndex', None))
     transaction.from_address = to_normalized_address(json_dict.get('from', None))
     transaction.to_address = to_normalized_address(json_dict.get('to', None))
     transaction.value = hex_to_dec(json_dict.get('value', None))
     transaction.gas = hex_to_dec(json_dict.get('gas', None))
     transaction.gas_price = hex_to_dec(json_dict.get('gasPrice', None))
     transaction.input = json_dict.get('input', None)
     return transaction
 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
Beispiel #5
0
    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_block(self, json_dict):
        block = EthBlock()
        block.number = hex_to_dec(json_dict.get('number'))
        block.block_group = int(block.number // BUCKET_SIZE)
        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
Beispiel #7
0
    def extract_transfer_from_log(self, receipt_log):

        topics = receipt_log.topics
        if topics is None or len(topics) < 1:
            # This is normal, topics can be empty for anonymous events
            return None

        if (topics[0]).casefold() == 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
Beispiel #8
0
    def filter_transfer_from_log(self, receipt_log):

        topics = receipt_log.topics
        if 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

            erc20_transfer = EthErc20Transfer()
            erc20_transfer.erc20_token = to_normalized_address(
                receipt_log.address)
            erc20_transfer.erc20_from = word_to_address(topics_with_data[1])
            erc20_transfer.erc20_to = word_to_address(topics_with_data[2])
            erc20_transfer.erc20_value = hex_to_dec(topics_with_data[3])
            erc20_transfer.erc20_tx_hash = receipt_log.transaction_hash
            erc20_transfer.erc20_log_index = receipt_log.log_index
            erc20_transfer.erc20_block_number = receipt_log.block_number
            return erc20_transfer

        return None
Beispiel #9
0
    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