Ejemplo n.º 1
0
    def AddContract(self, contract):
        """
        Add a contract to the database.

        Args:
            contract(neo.SmartContract.Contract): a Contract instance.
        """
        super(UserWallet, self).AddContract(contract)

        try:
            db_contract = Contract.get(ScriptHash=contract.ScriptHash.ToBytes())
            db_contract.delete_instance()
        except Exception as e:
            logger.info("contract does not exist yet")

        sh = bytes(contract.ScriptHash.ToArray())
        address, created = Address.get_or_create(ScriptHash=sh)
        address.IsWatchOnly = False
        address.save()
        db_contract = Contract.create(RawData=contract.ToArray(),
                                      ScriptHash=contract.ScriptHash.ToBytes(),
                                      PublicKeyHash=contract.PublicKeyHash.ToBytes(),
                                      Address=address,
                                      Account=self.__dbaccount)

        logger.debug("Creating db contract %s " % db_contract)

        db_contract.save()
Ejemplo n.º 2
0
    def DeleteAddress(self, script_hash):
        success, coins_toremove = super(UserWallet, self).DeleteAddress(script_hash)

        for coin in coins_toremove:
            try:
                c = Coin.get(TxId=bytes(coin.Reference.PrevHash.Data), Index=coin.Reference.PrevIndex)
                c.delete_instance()
            except Exception as e:
                logger.error("Could not delete coin %s %s " % (coin, e))

        todelete = bytes(script_hash.ToArray())

        for c in Contract.select():

            address = c.Address
            if address.ScriptHash == todelete:
                c.delete_instance()
                address.delete_instance()

        try:
            address = Address.get(ScriptHash=todelete)
            address.delete_instance()
        except Exception as e:
            pass

        return True, coins_toremove
Ejemplo n.º 3
0
    def Addresses(self):
        result = []
        try:
            for addr in Address.select():
                result.append(addr.ToString())
        except Exception as e:
            pass

        return result
Ejemplo n.º 4
0
    def Addresses(self):
        result = []
        try:
            for addr in Address.select():
                result.append(addr.ToString())
        except Exception as e:
            pass

        return result
Ejemplo n.º 5
0
    def AddWatchOnly(self, script_hash):
        super(UserWallet, self).AddWatchOnly(script_hash)

        script_hash_bytes = bytes(script_hash.ToArray())
        address = None

        try:
            address = Address.get(ScriptHash=script_hash_bytes)
        except Exception as e:
            # Address.DoesNotExist
            pass

        if address is None:
            address = Address.create(ScriptHash=script_hash_bytes, IsWatchOnly=True)
            address.save()
            return address
        else:
            raise Exception("Address already exists in wallet")
Ejemplo n.º 6
0
    def AddWatchOnly(self, script_hash):
        super(UserWallet, self).AddWatchOnly(script_hash)

        script_hash_bytes = bytes(script_hash.ToArray())
        address = None

        try:
            address = Address.get(ScriptHash=script_hash_bytes)
        except Exception as e:
            # Address.DoesNotExist
            pass

        if address is None:
            address = Address.create(ScriptHash=script_hash_bytes,
                                     IsWatchOnly=True)
            address.save()
            return address
        else:
            raise Exception("Address already exists in wallet")
Ejemplo n.º 7
0
    def OnCoinsChanged(self, added, changed, deleted):
        for coin in added:
            addr_hash = bytes(coin.Output.ScriptHash.Data)

            try:
                address = Address.get(ScriptHash=addr_hash)

                c = Coin(TxId=bytes(coin.Reference.PrevHash.Data),
                         Index=coin.Reference.PrevIndex,
                         AssetId=bytes(coin.Output.AssetId.Data),
                         Value=coin.Output.Value.value,
                         ScriptHash=bytes(coin.Output.ScriptHash.Data),
                         State=coin.State,
                         Address=address)
                c.save()
                logger.debug("saved coin %s " % c)
            except Exception as e:
                logger.error("COULDN'T SAVE!!!! %s " % e)
                raise

        for coin in changed:
            for hold in self._holds:
                if hold.Reference == coin.Reference and coin.State & CoinState.Spent > 0:
                    hold.IsComplete = True
                    hold.save()
            try:
                c = Coin.get(TxId=bytes(coin.Reference.PrevHash.Data),
                             Index=coin.Reference.PrevIndex)
                c.State = coin.State
                c.save()
            except Exception as e:
                logger.error(
                    "Coulndn't change coin %s %s (coin to change not found)" %
                    (coin, e))
                raise

        for coin in deleted:
            for hold in self._holds:
                if hold.Reference == coin.Reference:
                    hold.IsComplete = True
                    hold.save()
            try:
                c = Coin.get(TxId=bytes(coin.Reference.PrevHash.Data),
                             Index=coin.Reference.PrevIndex)
                c.delete_instance()

            except Exception as e:
                logger.error("could not delete coin %s %s " % (coin, e))
                raise
Ejemplo n.º 8
0
    def LoadWatchOnly(self):
        items = []

        try:
            for addr in Address.select():
                if addr.IsWatchOnly:
                    watchOnly = UInt160(data=addr.ScriptHash)
                    items.append(watchOnly)

            return items

        except Exception as e:
            logger.error("Could not load watch only: %s. You may need to migrate your wallet. Run 'wallet migrate'." % e)

        return []
Ejemplo n.º 9
0
    def LoadWatchOnly(self):
        items = []

        try:
            for addr in Address.select():
                if addr.IsWatchOnly:
                    watchOnly = UInt160(data=addr.ScriptHash)
                    items.append(watchOnly)

            return items

        except Exception as e:
            logger.error("Could not load watch only: %s. You may need to migrate your wallet. Run 'wallet migrate'." % e)

        return []
Ejemplo n.º 10
0
    def OnCoinsChanged(self, added, changed, deleted):

        for coin in added:
            addr_hash = bytes(coin.Output.ScriptHash.Data)

            try:
                address = Address.get(ScriptHash=addr_hash)

                c = Coin(
                    TxId=bytes(coin.Reference.PrevHash.Data),
                    Index=coin.Reference.PrevIndex,
                    AssetId=bytes(coin.Output.AssetId.Data),
                    Value=coin.Output.Value.value,
                    ScriptHash=bytes(coin.Output.ScriptHash.Data),
                    State=coin.State,
                    Address=address
                )
                c.save()
                logger.debug("saved coin %s " % c)
            except Exception as e:
                logger.error("COULDN'T SAVE!!!! %s " % e)

        for coin in changed:
            for hold in self._holds:
                if hold.Reference == coin.Reference and coin.State & CoinState.Spent > 0:
                    hold.IsComplete = True
                    hold.save()
            try:
                c = Coin.get(TxId=bytes(coin.Reference.PrevHash.Data), Index=coin.Reference.PrevIndex)
                c.State = coin.State
                c.save()
            except Exception as e:
                logger.error("Coulndn't change coin %s %s (coin to change not found)" % (coin, e))

        for coin in deleted:
            for hold in self._holds:
                if hold.Reference == coin.Reference:
                    hold.IsComplete = True
                    hold.save()
            try:
                c = Coin.get(TxId=bytes(coin.Reference.PrevHash.Data), Index=coin.Reference.PrevIndex)
                c.delete_instance()

            except Exception as e:
                logger.error("could not delete coin %s %s " % (coin, e))
Ejemplo n.º 11
0
    def DeleteAddress(self, script_hash):

        success, coins_toremove = super(UserWallet,
                                        self).DeleteAddress(script_hash)

        for coin in coins_toremove:
            try:
                c = Coin.get(TxId=bytes(coin.Reference.PrevHash.Data),
                             Index=coin.Reference.PrevIndex)
                c.delete_instance()
                print("deleted coin!!!")
            except Exception as e:
                print("Couldnt delete coin %s %s " % (e, coin))
                self.__log.debug("could not delete coin %s %s " % (coin, e))

        address = Address.get(ScriptHash=bytes(script_hash.ToArray()))
        address.delete_instance()

        return True, coins_toremove
Ejemplo n.º 12
0
    def __init__(self, public, is_mainnet):
        self._path = 'main123' if is_mainnet else 'test123'
        self.AddressVersion = 23
        self._lock = RLock()
        self._indexedDB = Blockchain.Default()
        self.BuildDatabase()


        self._keys = {}
        self._contracts = self.LoadContracts()
#        for public in ['0294cd0a9e77f358f709e69d9375680b1eafe75373645192b5b251260f484577ea']:
        kp = OnlyPublicKeyPair(public)
        self._keys[kp.PublicKeyHash.ToBytes()] = kp
        contract = WalletContract.CreateSignatureContract(kp.PublicKey)
        if contract.ScriptHash.ToBytes() not in self._contracts.keys():
            self._contracts[contract.ScriptHash.ToBytes()] = contract
            sh = bytes(contract.ScriptHash.ToArray())
            address, created = Address.get_or_create(ScriptHash=sh)
            address.IsWatchOnly = False
            address.save()
            db_contract = Contract.create(RawData=contract.ToArray(),
                    ScriptHash=contract.ScriptHash.ToBytes(),
                    PublicKeyHash=contract.PublicKeyHash.ToBytes(),
                    Address=address,
                    Account=None
            )






        self.LoadNamedAddresses()
        self._watch_only = self.LoadWatchOnly()
        self._tokens = self.LoadNEP5Tokens()
        self._coins = self.LoadCoins()
        self.initialize_holds()
        try:
            self._current_height = int(self.LoadStoredData('Height'))
        except:
            print('setting height to 0')
            self._current_height = 0
            self.SaveStoredData('Height', self._current_height)
Ejemplo n.º 13
0
    def OnCoinsChanged(self, added, changed, deleted):

        if len(added) > 0 or len(changed) > 0 or len(deleted) > 0:
            pass

        for coin in added:
            addr_hash = bytes(coin.Output.ScriptHash.Data)
            address = Address.get(ScriptHash=addr_hash)

            try:
                c = Coin(TxId=bytes(coin.Reference.PrevHash.Data),
                         Index=coin.Reference.PrevIndex,
                         AssetId=bytes(coin.Output.AssetId.Data),
                         Value=coin.Output.Value.value,
                         ScriptHash=bytes(coin.Output.ScriptHash.Data),
                         State=coin.State,
                         Address=address)
                c.save()
                self.__log.debug("saved coin %s " % c)
            except Exception as e:
                print("COLUDNT SAVE!!!! %s " % e)

        for coin in changed:
            try:
                c = Coin.get(TxId=bytes(coin.Reference.PrevHash.Data),
                             Index=coin.Reference.PrevIndex)
                c.State = coin.State
                c.save()
            except Exception as e:
                print("Coulndnt change coin %s %s" % (coin, e))
                self.__log.debug("coin to change not found! %s %s " %
                                 (coin, e))

        for coin in deleted:
            try:
                c = Coin.get(TxId=bytes(coin.Reference.PrevHash.Data),
                             Index=coin.Reference.PrevIndex)
                c.delete_instance()

            except Exception as e:
                print("Couldnt delete coin %s %s " % (e, coin))
                self.__log.debug("could not delete coin %s %s " % (coin, e))
Ejemplo n.º 14
0
    def OnCoinsChanged(self, added, changed, deleted):

        for coin in added:
            addr_hash = bytes(coin.Output.ScriptHash.Data)

            try:
                address = Address.get(ScriptHash=addr_hash)

                c = Coin(TxId=bytes(coin.Reference.PrevHash.Data),
                         Index=coin.Reference.PrevIndex,
                         AssetId=bytes(coin.Output.AssetId.Data),
                         Value=coin.Output.Value.value,
                         ScriptHash=bytes(coin.Output.ScriptHash.Data),
                         State=coin.State,
                         Address=address)
                c.save()
            except Exception as e:
                logger.error("[Path: %s ] Could not create coin: %s " %
                             (self._path, e))

        for coin in changed:
            try:
                c = Coin.get(TxId=bytes(coin.Reference.PrevHash.Data),
                             Index=coin.Reference.PrevIndex)
                c.State = coin.State
                c.save()
            except Exception as e:
                logger.error(
                    "[Path: %s ] could not change coin %s %s (coin to change not found)"
                    % (self._path, coin, e))

        for coin in deleted:
            try:
                c = Coin.get(TxId=bytes(coin.Reference.PrevHash.Data),
                             Index=coin.Reference.PrevIndex)
                c.delete_instance()
            except Exception as e:
                logger.error("[Path: %s] could not delete coin %s %s " %
                             (self._path, coin, e))
Ejemplo n.º 15
0
    def ToJson(self, verbose=False):
        assets = self.GetCoinAssets()
        tokens = list(self._tokens.values())
        assets = assets + tokens

        if Blockchain.Default().Height == 0:
            percent_synced = 0
        else:
            percent_synced = int(100 * self._current_height / Blockchain.Default().Height)

        jsn = {}
        jsn['path'] = self._path

        addresses = []
        has_watch_addr = False
        for addr in Address.select():
            logger.info("Script hash %s %s" % (addr.ScriptHash, type(addr.ScriptHash)))
            addr_str = Crypto.ToAddress(UInt160(data=addr.ScriptHash))
            acct = Blockchain.Default().GetAccountState(addr_str)
            token_balances = self.TokenBalancesForAddress(addr_str)
            if acct:
                json = acct.ToJson()
                json['is_watch_only'] = addr.IsWatchOnly
                addresses.append(json)
                if token_balances:
                    json['tokens'] = token_balances
                if addr.IsWatchOnly:
                    has_watch_addr = True
            else:
                script_hash = binascii.hexlify(addr.ScriptHash)
                json = {'address': addr_str, 'script_hash': script_hash.decode('utf8'), 'tokens': token_balances}
                addresses.append(json)

        balances = []
        watch_balances = []
        for asset in assets:
            if type(asset) is UInt256:
                bc_asset = Blockchain.Default().GetAssetState(asset.ToBytes())
                total = self.GetBalance(asset).value / Fixed8.D
                watch_total = self.GetBalance(asset, CoinState.WatchOnly).value / Fixed8.D
                balances.append("[%s]: %s " % (bc_asset.GetName(), total))
                watch_balances.append("[%s]: %s " % (bc_asset.GetName(), watch_total))
            elif type(asset) is WalletNEP5Token:
                balances.append("[%s]: %s " % (asset.symbol, self.GetBalance(asset)))
                watch_balances.append("[%s]: %s " % (asset.symbol, self.GetBalance(asset, True)))

        tokens = []
        for t in self._tokens.values():
            tokens.append(t.ToJson())

        jsn['addresses'] = addresses
        jsn['height'] = self._current_height
        jsn['percent_synced'] = percent_synced
        jsn['synced_balances'] = balances

        if has_watch_addr:
            jsn['synced_watch_only_balances'] = watch_balances

        jsn['public_keys'] = self.PubKeys()
        jsn['tokens'] = tokens

        jsn['claims'] = {
            'available': self.GetAvailableClaimTotal().ToString(),
            'unavailable': self.GetUnavailableBonus().ToString()
        }

        alia = NamedAddress.select()
        if len(alia):
            na = {}
            for n in alia:
                na[n.Title] = n.ToString()
            jsn['named_addr'] = na

        if verbose:
            jsn['coins'] = [coin.ToJson() for coin in self.FindUnspentCoins()]
            jsn['transactions'] = [tx.ToJson() for tx in self.GetTransactions()]
        return jsn
Ejemplo n.º 16
0
    def pretty_print(self, verbose=False):
        if Blockchain.Default().Height == 0:
            percent_synced = 0
        else:
            percent_synced = int(100 * self._current_height /
                                 Blockchain.Default().Height)

        print(f"Path       : {self._path}")
        print(f"Height     : {self._current_height}")
        print(f"Sync status: {percent_synced}%")
        print(" ")

        # collect available public keys
        pubkeys = dict()
        for k in self.LoadKeyPairs().values():
            pub = k.PublicKey.encode_point(True)
            for ct in self._contracts.values():
                if ct.PublicKeyHash == k.PublicKeyHash:
                    pubkeys.update({ct.Address: pub.decode('utf-8')})

        # build data objects
        addresses = dict()
        for addr in Address.select():
            addr_str = addr.ToString()
            addresses.update({
                addr_str: {
                    'public_key': pubkeys.get(addr_str, "N/A"),
                    'script_hash': addr.ScriptHash,
                    'watchonly': addr.IsWatchOnly,
                    'assets': self._get_asset_balances(addr_str,
                                                       addr.IsWatchOnly),
                    'tokens': self._get_token_balances(addr_str)
                }
            })

        aliases = dict()
        alia = NamedAddress.select()
        for n in alia:
            aliases[n.Title] = n.ToString()

        # pretty print
        for address, data in addresses.items():
            for title, addr in aliases.items():
                if address == addr:
                    print(f"Alias      : {title}")
            addr_str = address + " (watch only)" if data[
                'watchonly'] else address
            print(f"Address    : {addr_str}")
            if verbose:
                scripthash_le = binascii.hexlify(data['script_hash']).decode()
                scripthash_be = UInt160(data=data['script_hash']).To0xString()
                print(f"Public key : {data['public_key']}")
                print(f"Script hash: {data['script_hash']}")
                print(f"               little endian: {scripthash_le}")
                print(f"                  big endian: {scripthash_be}")
            has_balances = False
            for asset_name, value in data['assets'].items():
                if value > 0:
                    symbol = f"[{asset_name}]"
                    print(f"{symbol:<11}: {value}")
                    has_balances = True
            for token_name, value in data['tokens'].items():
                if value > 0:
                    symbol = f"[{token_name}]"
                    print(f"{symbol:<11}: {value}")
                    has_balances = True
            if not has_balances:
                print(f"{'Balances':<11}: only zero")
            print(" ")

        print("Claims:")
        print(f"   unlocked: {self.GetAvailableClaimTotal().ToString()}")
        print(f"   locked  : {self.GetUnavailableBonus().ToString()}")
Ejemplo n.º 17
0
    def ToJson(self, verbose=False):
        assets = self.GetCoinAssets()
        tokens = list(self._tokens.values())
        assets = assets + tokens

        if Blockchain.Default().Height == 0:
            percent_synced = 0
        else:
            percent_synced = int(100 * self._current_height / Blockchain.Default().Height)

        jsn = {}
        jsn['path'] = self._path

        addresses = []
        has_watch_addr = False
        for addr in Address.select():
            logger.info("Script hash %s %s" % (addr.ScriptHash, type(addr.ScriptHash)))
            addr_str = Crypto.ToAddress(UInt160(data=addr.ScriptHash))
            acct = Blockchain.Default().GetAccountState(addr_str)
            token_balances = self.TokenBalancesForAddress(addr_str)
            if acct:
                json = acct.ToJson()
                json['is_watch_only'] = addr.IsWatchOnly
                addresses.append(json)
                if token_balances:
                    json['tokens'] = token_balances
                if addr.IsWatchOnly:
                    has_watch_addr = True
            else:
                script_hash = binascii.hexlify(addr.ScriptHash)
                json = {'address': addr_str, 'script_hash': script_hash.decode('utf8'), 'tokens': token_balances}
                addresses.append(json)

        balances = []
        watch_balances = []
        for asset in assets:
            if type(asset) is UInt256:
                bc_asset = Blockchain.Default().GetAssetState(asset.ToBytes())
                total = self.GetBalance(asset).value / Fixed8.D
                watch_total = self.GetBalance(asset, CoinState.WatchOnly).value / Fixed8.D
                balances.append("[%s]: %s " % (bc_asset.GetName(), total))
                watch_balances.append("[%s]: %s " % (bc_asset.GetName(), watch_total))
            elif type(asset) is WalletNEP5Token:
                balances.append("[%s]: %s " % (asset.symbol, self.GetBalance(asset)))
                watch_balances.append("[%s]: %s " % (asset.symbol, self.GetBalance(asset, True)))

        tokens = []
        for t in self._tokens.values():
            tokens.append(t.ToJson())

        jsn['addresses'] = addresses
        jsn['height'] = self._current_height
        jsn['percent_synced'] = percent_synced
        jsn['synced_balances'] = balances

        if has_watch_addr:
            jsn['synced_watch_only_balances'] = watch_balances

        jsn['public_keys'] = self.PubKeys()
        jsn['tokens'] = tokens

        jsn['claims'] = {
            'available': self.GetAvailableClaimTotal().ToString(),
            'unavailable': self.GetUnavailableBonus().ToString()
        }

        alia = NamedAddress.select()
        if len(alia):
            na = {}
            for n in alia:
                na[n.Title] = n.ToString()
            jsn['named_addr'] = na

        if verbose:
            jsn['coins'] = [coin.ToJson() for coin in self.FindUnspentCoins()]
            jsn['transactions'] = [tx.ToJson() for tx in self.GetTransactions()]
        return jsn