def extract_transfer_from_log(self, receipt_log: Union[KlaytnRawReceiptLog, KlaytnReceiptLog]) -> Union[KlaytnRawTokenTransfer, KlaytnTokenTransfer, None]:

        if self.enrich and not isinstance(receipt_log, KlaytnReceiptLog):
            logger.warning("Cannot extract enrich token transfer from raw receipt log. It will return raw token transfer.")

        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

            if not self.enrich or not isinstance(receipt_log, KlaytnReceiptLog):
                token_transfer = KlaytnRawTokenTransfer()
                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.log_index = receipt_log.log_index
                token_transfer.transaction_hash = receipt_log.transaction_hash
                token_transfer.transaction_index = receipt_log.transaction_index
                token_transfer.block_number = receipt_log.block_number
                token_transfer.block_hash = receipt_log.block_hash

                return token_transfer

            else:
                token_transfer = KlaytnTokenTransfer()
                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.log_index = receipt_log.log_index
                token_transfer.transaction_hash = receipt_log.transaction_hash
                token_transfer.transaction_index = receipt_log.transaction_index
                token_transfer.block_number = receipt_log.block_number
                token_transfer.block_hash = receipt_log.block_hash
                # enrich
                token_transfer.block_timestamp = receipt_log.block_timestamp
                token_transfer.block_unix_timestamp = receipt_log.block_unix_timestamp
                token_transfer.transaction_receipt_status = receipt_log.transaction_receipt_status

                return token_transfer

        return None
示例#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
    def json_dict_to_transaction(
            self, json_dict,
            **kwargs) -> Union[KlaytnTransaction, KlaytnRawTransaction]:
        _transaction = KlaytnRawTransaction()

        _transaction.hash = json_dict.get('transactionHash')
        _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.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')

        # Klaytn additional properties
        _transaction.fee_payer = json_dict.get('feePayer')
        _transaction.fee_payer_signatures = json_dict.get('feePayerSignatures')
        # FIXME: deal with null input
        _transaction.fee_ratio = hex_to_dec(json_dict.get('feeRatio'))

        _transaction.sender_tx_hash = json_dict.get('senderTxHash')
        _transaction.signatures = json_dict.get('signatures')

        _transaction.tx_type = json_dict.get('type')
        _transaction.tx_type_int = json_dict.get('typeInt')

        if self.enrich and 'logs' in json_dict:
            _transaction.logs = [
                self.receipt_log_mapper.json_dict_to_receipt_log(
                    log,
                    block_timestamp=kwargs.get('block_timestamp'),
                    block_timestamp_fos=kwargs.get('block_timestamp_fos'),
                    transaction_receipt_status=hex_to_dec(
                        json_dict.get('status')),
                    enrich=self.enrich) for log in json_dict['logs']
            ]
        else:
            del _transaction.logs

        return _transaction if not self.enrich else KlaytnTransaction.enrich(
            _transaction,
            block_timestamp=kwargs.get('block_timestamp'),
            block_timestamp_fos=kwargs.get('block_timestamp_fos'),
            receipt_gas_used=hex_to_dec(json_dict.get('gasUsed')),
            receipt_status=hex_to_dec(json_dict.get('status')),
            receipt_contract_address=to_normalized_address(
                json_dict.get('contractAddress')))
示例#4
0
    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
示例#6
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
    def json_dict_to_transaction(self, json_dict, **kwargs):
        transaction = EthTransaction()
        transaction.hash = json_dict.get('transactionHash')
        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')

        # Klaytn additional properties
        transaction.fee_payer = json_dict.get('feePayer')
        transaction.fee_payer_signatures = json_dict.get('feePayerSignatures')
        # FIXME: deal with null input
        transaction.fee_ratio = hex_to_dec(json_dict.get('feeRatio'))

        transaction.sender_tx_hash = json_dict.get('senderTxHash')
        transaction.signatures = json_dict.get('signatures')

        transaction.tx_type = json_dict.get('type')
        transaction.tx_type_int = json_dict.get('typeInt')

        return transaction
示例#8
0
    def json_dict_to_receipt_log(self, json_dict, **kwargs) -> Union[KlaytnRawReceiptLog, KlaytnReceiptLog]:
        _receipt_log = KlaytnRawReceiptLog()

        _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 if not self.enrich else KlaytnReceiptLog.enrich(_receipt_log,
            block_timestamp=kwargs.get('block_timestamp'),
            block_timestamp_fos=kwargs.get('transaction_receipt_status'),
            transaction_receipt_status=kwargs.get('transaction_receipt_status'))
示例#9
0
    def json_dict_to_receipt(self, json_dict) -> KlaytnRawReceipt:
        receipt = KlaytnRawReceipt()

        receipt.transaction_hash = json_dict.get('hash')
        receipt.transaction_index = hex_to_dec(json_dict.get('index'))
        receipt.block_hash = json_dict.get('blockHash')
        receipt.block_number = hex_to_dec(json_dict.get('blockNumber'))

        receipt.gas_used = hex_to_dec(json_dict.get('gasUsed'))
        receipt.contract_address = to_normalized_address(
            json_dict.get('contractAddress'))
        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
示例#10
0
    def json_dict_to_block(self,
                           json_dict) -> Union[KlaytnRawBlock, KlaytnBlock]:
        _block = KlaytnRawBlock()
        _block.number = hex_to_dec(json_dict.get('number'))
        _block.hash = json_dict.get('hash')
        _block.parent_hash = json_dict.get('parentHash')
        _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.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'))
        _block.timestamp_fos = hex_to_dec(json_dict.get('timestampFoS'))

        # Klaytn additional properties
        _block.block_score = hex_to_dec(json_dict.get('blockscore'))
        _block.total_block_score = hex_to_dec(json_dict.get('totalBlockScore'))

        _block.governance_data = json_dict.get('governanceData')
        _block.vote_data = json_dict.get('voteData')

        _block.committee = json_dict.get('committee')
        _block.proposer = json_dict.get('proposer')
        _block.reward_address = json_dict.get('reward')

        if 'transactions' in json_dict:
            _block.transactions = [
                self.transaction_mapper.json_dict_to_transaction(
                    tx,
                    block_timestamp=_block.timestamp,
                    block_timestamp_fos=_block.timestamp_fos,
                    enrich=self.enrich) for tx in json_dict['transactions']
                if isinstance(tx, dict)
            ]
            _block.transaction_count = len(json_dict['transactions'])

            if not self.enrich:
                _block.receipts = [
                    self.receipt_mapper.json_dict_to_receipt(tx)
                    for tx in json_dict['transactions']
                ]
            else:
                del _block.receipts

        return _block if not self.enrich else KlaytnBlock.enrich(_block)
示例#11
0
    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'))

        # Klaytn additional properties
        block.block_score = hex_to_dec(json_dict.get('blockscore'))
        block.total_block_score = hex_to_dec(json_dict.get('totalBlockScore'))

        block.timestamp_fos = hex_to_dec(json_dict.get('timestampFoS'))
        block.governance_data = json_dict.get('governanceData')
        block.vote_data = json_dict.get('voteData')

        block.committee = json_dict.get('committee')
        block.proposer = json_dict.get('proposer')
        block.reward_address = json_dict.get('reward')

        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
示例#12
0
    def block_json_dict_to_events(self, block_json_dict, event_hash=None):
        events = []

        block = EthBlock()
        block.number = hex_to_dec(block_json_dict.get('number'))
        block.hash = block_json_dict.get('hash')
        block.timestamp = hex_to_dec(block_json_dict.get('timestamp'))
        block.timestamp_fos = hex_to_dec(block_json_dict.get('timestampFoS'))
        if 'transactions' in block_json_dict:
            for tx_json_dict in block_json_dict['transactions']:
                if isinstance(tx_json_dict, dict):
                    transaction = EthTransaction()
                    transaction.hash = tx_json_dict.get('transactionHash')
                    transaction.index = hex_to_dec(tx_json_dict.get('transactionIndex'))
                    transaction.status = hex_to_dec(tx_json_dict.get('status'))
                    if 'logs' in tx_json_dict:
                        for log_json_dict in tx_json_dict['logs']:
                            if isinstance(log_json_dict, dict):
                                event = KlaytnEvent()

                                event.block_number = block.number
                                event.block_hash = block.hash
                                event.block_timestamp = block.timestamp
                                event.block_timestamp_fos = block.timestamp_fos
                                event.transaction_hash = transaction.hash
                                event.transaction_index = transaction.index
                                event.transaction_status = transaction.status
                                event.log_index = hex_to_dec(log_json_dict.get('logIndex'))
                                event.log_address = log_json_dict.get('address')
                                event.log_data = log_json_dict.get('data')
                                event.log_topics = self._safe_convert_to_topics(log_json_dict.get('topics'))

                                if self._match_first_hash(event.log_topics, event_hash) is True:
                                    events.append(event)

        return events