def transaction_from_explorer_transaction(etxn, resp=None):  # keyword parameters for error handling purposes only
    if resp is None:
        resp = {}
    # parse the transactions
    transaction = TransactionFactory.from_json(etxn["rawtransaction"], etxn["id"])
    # add the parent (coin) outputs
    coininputoutputs = etxn.get("coininputoutputs", None) or []
    if len(transaction.coin_inputs) != len(coininputoutputs):
        raise Exception(
            "amount of coin inputs and parent outputs are not matching: {} != {}".format(
                len(transaction.coin_inputs), len(coininputoutputs)
            )
        )
    for (idx, co) in enumerate(coininputoutputs):
        co = CoinOutput.from_json(obj=co)
        co.id = transaction.coin_inputs[idx].parentid
        transaction.coin_inputs[idx].parent_output = co
    # add the coin output ids
    coinoutputids = etxn.get("coinoutputids", None) or []
    if len(transaction.coin_outputs) != len(coinoutputids):
        raise Exception(
            "amount of coin outputs and output identifiers are not matching: {} != {}".format(
                len(transaction.coin_outputs), len(coinoutputids)
            )
        )
    for (idx, id) in enumerate(coinoutputids):
        transaction.coin_outputs[idx].id = Hash.from_json(obj=id)
    # add the parent (blockstake) outputs
    blockstakeinputoutputs = etxn.get("blockstakeinputoutputs", None) or []
    if len(transaction.blockstake_inputs) != len(blockstakeinputoutputs):
        raise Exception(
            "amount of blockstake inputs and parent outputs are not matching: {} != {}".format(
                len(transaction.blockstake_inputs), len(blockstakeinputoutputs)
            )
        )
    for (idx, bso) in enumerate(blockstakeinputoutputs):
        bso = BlockstakeOutput.from_json(obj=bso)
        bso.id = transaction.blockstake_inputs[idx].parentid
        transaction.blockstake_inputs[idx].parent_output = bso
    # add the blockstake output ids
    blockstakeoutputids = etxn.get("blockstakeoutputids", None) or []
    if len(transaction.blockstake_outputs) != len(blockstakeoutputids):
        raise Exception(
            "amount of blokstake outputs and output identifiers are not matching: {} != {}".format(
                len(transaction.blockstake_inputs), len(blockstakeoutputids)
            )
        )
    for (idx, id) in enumerate(blockstakeoutputids):
        transaction.blockstake_outputs[idx].id = Hash.from_json(obj=id)
    # set the unconfirmed state
    transaction.unconfirmed = etxn.get("unconfirmed", False)
    # set the height of the transaction only if confirmed
    if not transaction.unconfirmed:
        transaction.height = int(etxn.get("height"))
    # return the transaction
    return transaction
 def __init__(self):
     # personal wallet outputs
     self._outputs = {}
     self._outputs_spent = {}
     self._outputs_unconfirmed = {}
     self._outputs_unconfirmed_spent = {}
     # balance chain context
     self._chain_time = 0
     self._chain_height = 0
     self._chain_blockid = Hash()
     # all wallet addresses tracked in this wallet
     self._addresses = set()
 def chain_blockid(self, value):
     """
     Set the blockchain block ID, such that applications that which to cache this
     balance object could ensure that the last block is still the same as the
     last known block known by this balance instance.
     """
     if not value:
         self._chain_blockid = Hash()
         return
     if isinstance(value, Hash):
         self._chain_blockid.value = value.value
     else:
         self._chain_blockid.value = value