Exemplo n.º 1
0
    def LoadCoins(self):

        coins = []

        for coin in Coin.select():
            reference = CoinReference(prev_hash=coin.TxId,
                                      prev_index=coin.Index)
            output = TransactionOutput(coin.AssetId, coin.Value,
                                       coin.ScriptHash)
            walletcoin = WalletCoin.CoinFromRef(reference, output, coin.State)
            coins.append(walletcoin)

        return coins
Exemplo n.º 2
0
    def LoadCoins(self):
        coins = {}

        try:
            for coin in Coin.select():
                reference = CoinReference(prev_hash=UInt256(coin.TxId), prev_index=coin.Index)
                output = TransactionOutput(UInt256(coin.AssetId), Fixed8(coin.Value), UInt160(coin.ScriptHash))
                walletcoin = WalletCoin.CoinFromRef(reference, output, coin.State)
                coins[reference] = walletcoin
        except Exception as e:
            logger.error("could not load coins %s " % e)

        return coins
Exemplo n.º 3
0
    def ProcessNewBlock(self, block):

        added = set()
        changed = set()
        deleted = set()

        try:

            for tx in block.FullTransactions:

                for index, output in enumerate(tx.outputs):

                    state = self.CheckAddressState(output.ScriptHash)

                    if state & AddressState.InWallet > 0:

                        key = CoinReference(tx.Hash, index)

                        if key in self._coins.keys():
                            coin = self._coins[key]
                            coin.State |= CoinState.Confirmed
                            changed.add(coin)

                        else:
                            newcoin = Coin.CoinFromRef(
                                coin_ref=key,
                                tx_output=output,
                                state=CoinState.Confirmed)
                            self._coins[key] = newcoin
                            added.add(newcoin)

                        if state & AddressState.WatchOnly > 0:

                            self._coins[key].State |= CoinState.WatchOnly
                            changed.add(self._coins[key])

            for tx in block.FullTransactions:

                for input in tx.inputs:

                    if input in self._coins.keys():

                        if self._coins[input].Output.AssetId.ToBytes(
                        ) == Blockchain.SystemShare().Hash.ToBytes():
                            self._coins[
                                input].State |= CoinState.Spent | CoinState.Confirmed
                            changed.add(self._coins[input])

                        else:
                            deleted.add(self._coins[input])
                            del self._coins[input]

            for claimTx in [
                    tx for tx in block.Transactions
                    if tx.Type == TransactionType.ClaimTransaction
            ]:

                for ref in claimTx.Claims:
                    if ref in self._coins.keys():
                        deleted.add(self._coins[ref])
                        del self._coins[ref]

            self._current_height += 1
            self.OnProcessNewBlock(block, added, changed, deleted)

            if len(added) + len(deleted) + len(changed) > 0:
                self.BalanceChanged()

        except Exception as e:
            traceback.print_stack()
            traceback.print_exc()
            print("could not process %s " % e)
Exemplo n.º 4
0
    def ProcessNewBlock(self, block):
        """
        Processes a block on the blockchain.  This should be done in a sequential order, ie block 4 should be
        only processed after block 3.

        Args:
            block: (neo.Core.Block) a block on the blockchain.
        """
        added = set()
        changed = set()
        deleted = set()

        try:
            # go through the list of transactions in the block and enumerate
            # over their outputs
            for tx in block.FullTransactions:

                for index, output in enumerate(tx.outputs):

                    # check to see if the outputs in the tx are in this wallet
                    state = self.CheckAddressState(output.ScriptHash)

                    if state & AddressState.InWallet > 0:

                        # if its in the wallet, check to see if the coin exists yet
                        key = CoinReference(tx.Hash, index)

                        # if it exists, update it, otherwise create a new one
                        if key in self._coins.keys():
                            coin = self._coins[key]
                            coin.State |= CoinState.Confirmed
                            changed.add(coin)
                        else:
                            newcoin = Coin.CoinFromRef(coin_ref=key, tx_output=output, state=CoinState.Confirmed, transaction=tx)
                            self._coins[key] = newcoin
                            added.add(newcoin)

                        if state & AddressState.WatchOnly > 0:
                            self._coins[key].State |= CoinState.WatchOnly
                            changed.add(self._coins[key])

            # now iterate over the inputs of the tx and do the same
            for tx in block.FullTransactions:

                for input in tx.inputs:

                    if input in self._coins.keys():
                        if self._coins[input].Output.AssetId == Blockchain.SystemShare().Hash:
                            coin = self._coins[input]
                            coin.State |= CoinState.Spent | CoinState.Confirmed
                            changed.add(coin)

                        else:
                            deleted.add(self._coins[input])
                            del self._coins[input]

            for claimTx in [tx for tx in block.Transactions if tx.Type == TransactionType.ClaimTransaction]:

                for ref in claimTx.Claims:
                    if ref in self._coins.keys():
                        deleted.add(self._coins[ref])
                        del self._coins[ref]

            # update the current height of the wallet
            self._current_height += 1

            # in the case that another wallet implementation needs to do something
            # with the coins that have been changed ( ie persist to db ) this
            # method is called
            self.OnProcessNewBlock(block, added, changed, deleted)

            # this is not necessary at the moment, but any outside process
            # that wants to subscribe to the balance changed event could do
            # so from the BalanceChanged method
            if len(added) + len(deleted) + len(changed) > 0:
                self.BalanceChanged()

        except Exception as e:
            traceback.print_stack()
            traceback.print_exc()
            logger.error("could not process %s " % e)
Exemplo n.º 5
0
    def SaveTransaction(self, tx):
        """
        This method is used to after a transaction has been made by this wallet.  It updates the states of the coins
        In the wallet to reflect the new balance, but the coins remain in a ``CoinState.UNCONFIRMED`` state until
        The transaction has been processed by the network.

        The results of these updates can be used by overriding the ``OnSaveTransaction`` method, and, for example
        persisting the results to a database.

        Args:
            tx (Transaction): The transaction that has been made by this wallet.

        Returns:
            bool: True is successfully processes, otherwise False if input is not in the coin list, already spent or not confirmed.
        """
        coins = self.GetCoins()
        changed = []
        added = []
        deleted = []
        found_coin = False
        for input in tx.inputs:
            coin = None

            for coinref in coins:
                test_coin = coinref.Reference
                if test_coin == input:
                    coin = coinref

            if coin is None:
                return False
            if coin.State & CoinState.Spent > 0:
                return False
            elif coin.State & CoinState.Confirmed == 0:
                return False

            coin.State |= CoinState.Spent
            coin.State &= ~CoinState.Confirmed
            changed.append(coin)

        for index, output in enumerate(tx.outputs):

            state = self.CheckAddressState(output.ScriptHash)

            key = CoinReference(tx.Hash, index)

            if state & AddressState.InWallet > 0:
                newcoin = Coin.CoinFromRef(coin_ref=key, tx_output=output, state=CoinState.Unconfirmed)
                self._coins[key] = newcoin

                if state & AddressState.WatchOnly > 0:
                    newcoin.State |= CoinState.WatchOnly

                added.append(newcoin)

        if isinstance(tx, ClaimTransaction):
            # do claim stuff
            for claim in tx.Claims:
                claim_coin = self._coins[claim]
                claim_coin.State |= CoinState.Claimed
                claim_coin.State &= ~CoinState.Confirmed
                changed.append(claim_coin)

        self.OnSaveTransaction(tx, added, changed, deleted)

        return True
Exemplo n.º 6
0
    def ProcessNewBlock(self, block):

        added = set()
        changed = set()
        deleted = set()

        self._lock.acquire()
        try:

            for tx in block.Transactions:

                for index, output in enumerate(tx.outputs):

                    state = self.CheckAddressState(output.ScriptHash)

                    if state > 0:
                        key = CoinReference(tx.Hash, index)

                        found = False
                        for coin in self._coins:
                            if coin.CoinRef.Equals(key):
                                coin.State |= CoinState.Confirmed
                                changed.add(coin.CoinRef)
                                found = True
                        if not found:
                            newcoin = Coin.CoinFromRef(
                                key, output, state=CoinState.Confirmed)
                            self._coins.append(newcoin)
                            added.add(newcoin.CoinRef)

                        if state == AddressState.WatchOnly:
                            for coin in self._coins:
                                if coin.CoinRef.Equals(key):
                                    coin.State |= CoinState.WatchOnly
                                    changed.add(coin.CoinRef)

            for tx in block.Transactions:

                for input in tx.inputs:

                    for coin in self._coins:
                        if coin.CoinRef.Equals(input):

                            if coin.TXOutput.AssetId == Blockchain.SystemShare(
                            ).Hash():
                                coin.State |= CoinState.Spent | CoinState.Confirmed
                                changed.add(coin.CoinRef)
                            else:
                                self._coins.remove(coin)
                                deleted.add(coin.CoinRef)

            for claimTx in [
                    tx for tx in block.Transactions
                    if tx.Type == TransactionType.ClaimTransaction
            ]:
                for ref in claimTx.Claims:
                    if ref in self._coins:
                        self._coins.remove(ref)
                        deleted.add(ref)

            self._current_height += 1
            self.OnProcessNewBlock(block, added, changed, deleted)

            if len(added) + len(deleted) + len(changed) > 0:
                self.BalanceChanged()

        except Exception as e:
            print("could not process: %s " % e)
        finally:
            self._lock.release()