Beispiel #1
0
def dict_to_spoof_transaction(
        chain: AsyncChain, header: BlockHeader,
        transaction_dict: Dict[str, Any]) -> SpoofTransaction:
    """
    Convert dicts used in calls & gas estimates into a spoof transaction
    """
    txn_dict = normalize_transaction_dict(transaction_dict)
    sender = txn_dict.get('from', ZERO_ADDRESS)

    if 'nonce' in txn_dict:
        nonce = txn_dict['nonce']
    else:
        vm = chain.get_vm(header)
        nonce = vm.state.account_db.get_nonce(sender)

    gas_price = txn_dict.get('gasPrice', 0)
    gas = txn_dict.get('gas', header.gas_limit)

    unsigned = chain.get_vm_class(header).create_unsigned_transaction(
        nonce=nonce,
        gas_price=gas_price,
        gas=gas,
        to=txn_dict['to'],
        value=txn_dict['value'],
        data=txn_dict['data'],
    )
    return SpoofTransaction(unsigned, from_=sender)
Beispiel #2
0
def receipt_to_dict(receipt: Receipt, tx_hash: Hash32,
                    chain: AsyncChain) -> Dict[str, str]:
    dict_to_return = all_rlp_fields_to_dict_camel_case(receipt)

    block_hash, index, is_receive = chain.chaindb.get_transaction_index(
        tx_hash)

    dict_to_return['blockHash'] = to_hex(block_hash)
    dict_to_return['transactionHash'] = to_hex(tx_hash)
    dict_to_return['isReceive'] = to_hex(is_receive)
    dict_to_return['transactionIndex'] = to_hex(index)

    block_header = chain.get_block_header_by_hash(block_hash)
    dict_to_return['blockNumber'] = to_hex(block_header.block_number)

    for i in range(len(dict_to_return['logs'])):
        dict_to_return['logs'][i]['logIndex'] = to_hex(i)
        dict_to_return['logs'][i]['transactionIndex'] = to_hex(index)
        dict_to_return['logs'][i]['transactionHash'] = to_hex(tx_hash)
        dict_to_return['logs'][i]['blockHash'] = to_hex(block_hash)
        dict_to_return['logs'][i]['blockNumber'] = to_hex(
            block_header.block_number)
        dict_to_return['logs'][i]['topics'] = [
            pad_hex(value, 32) for value in dict_to_return['logs'][i]['topics']
        ]

    transaction = chain.get_canonical_transaction(tx_hash)

    if is_receive:
        dict_to_return['to'] = to_hex(block_header.chain_address)
        dict_to_return['sender'] = to_hex(
            chain.chaindb.get_chain_wallet_address_for_block_hash(
                transaction.sender_block_hash))
    else:
        dict_to_return['to'] = to_hex(transaction.to)
        dict_to_return['sender'] = to_hex(transaction.sender)

        if transaction.to == CREATE_CONTRACT_ADDRESS:
            dict_to_return['contractAddress'] = to_hex(
                generate_contract_address(transaction.sender,
                                          transaction.nonce))

    dict_to_return['cumulativeGasUsed'] = to_hex(
        chain.chaindb.get_cumulative_gas_used(tx_hash))

    return dict_to_return
Beispiel #3
0
def receive_transaction_to_dict(transaction: BaseReceiveTransaction,
                                chain: AsyncChain) -> Dict[str, str]:
    tx_hash = transaction.hash
    dict_to_return = all_rlp_fields_to_dict_camel_case(transaction)
    dict_to_return['isReceive'] = to_hex(True)
    dict_to_return['hash'] = encode_hex(tx_hash)

    from_address = chain.get_block_header_by_hash(
        transaction.sender_block_hash).chain_address

    dict_to_return['from'] = to_hex(from_address)

    originating_transaction = chain.chaindb.get_transaction_by_hash(
        transaction.send_transaction_hash,
        send_tx_class=chain.get_vm().get_transaction_class(),
        receive_tx_class=chain.get_vm().get_receive_transaction_class())

    if transaction.is_refund:
        value = originating_transaction.remaining_refund
    else:
        value = originating_transaction.value

    dict_to_return['value'] = to_hex(value)
    dict_to_return['gasPrice'] = to_hex(originating_transaction.gas_price)
    dict_to_return['to'] = to_hex(originating_transaction.to)
    try:
        dict_to_return['gasUsed'] = to_hex(
            chain.chaindb.get_transaction_receipt(transaction.hash).gas_used)
    except TransactionNotFound:
        dict_to_return['gasUsed'] = to_hex(0)

    try:
        block_hash, receive_tx_index, _ = chain.chaindb.get_transaction_index(
            tx_hash)
        num_send_transactions = chain.chaindb.get_number_of_send_tx_in_block(
            block_hash)
        block_tx_index = num_send_transactions + receive_tx_index
        dict_to_return['transactionIndex'] = to_hex(block_tx_index)
        dict_to_return['blockHash'] = to_hex(block_hash)
    except TransactionNotFound:
        pass

    return dict_to_return
Beispiel #4
0
async def get_header(chain: AsyncChain, at_block: Union[str,
                                                        int]) -> BlockHeader:
    if at_block == 'pending':
        raise NotImplementedError(
            "RPC interface does not support the 'pending' block at this time")
    elif at_block == 'latest':
        at_header = chain.get_canonical_head()
    elif at_block == 'earliest':
        # TODO find if genesis block can be non-zero. Why does 'earliest' option even exist?
        block = await chain.coro_get_canonical_block_by_number(0)
        at_header = block.header
    # mypy doesn't have user defined type guards yet
    # https://github.com/python/mypy/issues/5206
    elif is_integer(at_block) and at_block >= 0:  # type: ignore
        block = await chain.coro_get_canonical_block_by_number(0)
        at_header = block.header
    else:
        raise TypeError("Unrecognized block reference: %r" % at_block)

    return at_header
Beispiel #5
0
async def account_db_at_block(chain: AsyncChain,
                              at_block: Union[str, int],
                              read_only: bool = True) -> BaseAccountDB:
    at_header = await get_header(chain, at_block)
    vm = chain.get_vm(at_header)
    return vm.state.account_db