Beispiel #1
0
        protected override void OnSaveTransaction(CoreTransaction tx, IEnumerable <WalletCoin> added, IEnumerable <WalletCoin> changed)
        {
            Transaction tx_changed = null;

            using (WalletDataContext ctx = new WalletDataContext(DbPath))
            {
                if (IsWalletTransaction(tx))
                {
                    tx_changed = ctx.Transactions.Add(new Transaction
                    {
                        Hash    = tx.Hash.ToArray(),
                        Type    = tx.Type,
                        RawData = tx.ToArray(),
                        Height  = null,
                        Time    = DateTime.Now
                    }).Entity;
                }
                OnCoinsChanged(ctx, added, changed, Enumerable.Empty <WalletCoin>());
                ctx.SaveChanges();
            }
            if (tx_changed != null)
            {
                TransactionsChanged?.Invoke(this, GetTransactionInfo(new[] { tx_changed }));
            }
        }
Beispiel #2
0
 public override void AddContract(VerificationContract contract)
 {
     base.AddContract(contract);
     using (WalletDataContext ctx = new WalletDataContext(DbPath))
     {
         Contract db_contract = ctx.Contracts.FirstOrDefault(p => p.ScriptHash.SequenceEqual(contract.ScriptHash.ToArray()));
         if (db_contract != null)
         {
             db_contract.PublicKeyHash = contract.PublicKeyHash.ToArray();
         }
         else
         {
             Address db_address = ctx.Addresses.FirstOrDefault(p => p.ScriptHash.SequenceEqual(contract.ScriptHash.ToArray()));
             if (db_address == null)
             {
                 ctx.Addresses.Add(new Address
                 {
                     ScriptHash = contract.ScriptHash.ToArray()
                 });
             }
             ctx.Contracts.Add(new Contract
             {
                 RawData       = contract.ToArray(),
                 ScriptHash    = contract.ScriptHash.ToArray(),
                 PublicKeyHash = contract.PublicKeyHash.ToArray()
             });
         }
         ctx.SaveChanges();
     }
 }
Beispiel #3
0
 protected override byte[] LoadStoredData(string name)
 {
     using (WalletDataContext ctx = new WalletDataContext(DbPath))
     {
         return(ctx.Keys.FirstOrDefault(p => p.Name == name)?.Value);
     }
 }
Beispiel #4
0
 public IEnumerable <TransactionInfo> LoadTransactions()
 {
     using (WalletDataContext ctx = new WalletDataContext(DbPath))
     {
         return(GetTransactionInfo(ctx.Transactions.ToArray()));
     }
 }
Beispiel #5
0
        public override bool DeleteKey(UInt160 publicKeyHash)
        {
            bool flag = base.DeleteKey(publicKeyHash);

            if (flag)
            {
                using (WalletDataContext ctx = new WalletDataContext(DbPath))
                {
                    Account account = ctx.Accounts.FirstOrDefault(p => p.PublicKeyHash.SequenceEqual(publicKeyHash.ToArray()));
                    if (account != null)
                    {
                        foreach (byte[] hash in ctx.Contracts.Where(p => p.PublicKeyHash.SequenceEqual(publicKeyHash.ToArray())).Select(p => p.ScriptHash))
                        {
                            Address address = ctx.Addresses.FirstOrDefault(p => p.ScriptHash.SequenceEqual(hash));
                            if (address != null)
                            {
                                ctx.Addresses.Remove(address);
                            }
                        }
                        ctx.Accounts.Remove(account);
                        ctx.SaveChanges();
                    }
                }
            }
            return(flag);
        }
Beispiel #6
0
 protected override IEnumerable <WalletKeyPairBase> LoadKeyPairs()
 {
     using (WalletDataContext ctx = new WalletDataContext(DbPath))
     {
         foreach (Account item in ctx.Accounts.Select(p => p))
         {
             if ((KeyType)item.nVersion == KeyType.Anonymous || (KeyType)item.nVersion == KeyType.Transparent)
             {
                 byte[]        decryptedPrivateKey = DecryptPrivateKey(item.PrivateKeyEncrypted);
                 WalletKeyPair account             = new WalletKeyPair(decryptedPrivateKey, (KeyType)item.nVersion);
                 Array.Clear(decryptedPrivateKey, 0, decryptedPrivateKey.Length);
                 yield return(account);
             }
             else if ((KeyType)item.nVersion == KeyType.Stealth)
             {
                 byte[]         decryptedPrivateKey = DecryptPrivateKey(item.PrivateKeyEncrypted);
                 byte[]         decryptedViewKey    = DecryptPrivateKey(item.PrivateViewKeyEncrypted);
                 StealthKeyPair account             = new StealthKeyPair(decryptedPrivateKey, decryptedViewKey);
                 Array.Clear(decryptedPrivateKey, 0, decryptedPrivateKey.Length);
                 Array.Clear(decryptedViewKey, 0, decryptedViewKey.Length);
                 yield return(account);
             }
         }
     }
 }
Beispiel #7
0
        public override void Rebuild()
        {
            lock (SyncRoot)
            {
                base.Rebuild();
                using (WalletDataContext ctx = new WalletDataContext(DbPath))
                {
                    ctx.Keys.First(p => p.Name == "Height").Value = BitConverter.GetBytes(0);

                    ctx.Database.ExecuteSqlCommand($"DELETE FROM [Transaction]"); //{nameof(Transaction)}
                    ctx.Database.ExecuteSqlCommand($"DELETE FROM [Coin]");        //{nameof(Coin)}
                    ctx.Database.ExecuteSqlCommand($"DELETE FROM [JSCoin]");      //{nameof(JSCoin)}
                    ctx.Database.ExecuteSqlCommand($"DELETE FROM [RCTCoin]");

                    byte[] cmTree = { 0x00, 0x00, 0x00 };                         // Commitment Merkle Tree Initial bytes.
                    ctx.Keys.First(p => p.Name == "CmMerkleTree").Value = cmTree; // Initialize the CmMerkleTree.

                    try
                    {
                        ctx.SaveChanges();
                    }
                    catch (Exception ex)
                    {
                        string strEx = ex.Message;
                    }
                }
            }
        }
Beispiel #8
0
 protected override IEnumerable <RCTWalletCoin> LoadRCTCoins()
 {
     using (WalletDataContext ctx = new WalletDataContext(DbPath))
     {
         foreach (RCTCoin coin in ctx.RCTCoins)
         {
             yield return(new RCTWalletCoin
             {
                 Reference = new RCTCoinReference
                 {
                     PrevHash = new UInt256(coin.TxId),
                     TxRCTHash = Cryptography.ECC.ECPoint.DecodePoint(coin.TxRCTHash, Cryptography.ECC.ECCurve.Secp256r1),
                     PrevRCTSigId = coin.RctID,
                     PrevRCTSigIndex = coin.Index
                 },
                 Output = new RCTransactionOutput
                 {
                     AssetId = new UInt256(coin.AssetId),
                     Value = new Fixed8(coin.Value),
                     PubKey = Cryptography.ECC.ECPoint.DecodePoint(coin.PubKey, Cryptography.ECC.ECCurve.Secp256r1),
                     ScriptHash = new UInt160(coin.ScriptHash)
                 },
                 State = coin.State
             });
         }
     }
 }
Beispiel #9
0
 protected override IEnumerable <JSWalletCoin> LoadJSCoins()
 {
     using (WalletDataContext ctx = new WalletDataContext(DbPath))
     {
         foreach (JSCoin coin in ctx.JSCoins)
         {
             yield return(new JSWalletCoin
             {
                 Reference = new JSCoinReference
                 {
                     PrevHash = new UInt256(coin.TxId),
                     PrevJsId = coin.JsId,
                     PrevIndex = coin.Index
                 },
                 Output = new JSTransactionOutput
                 {
                     AssetId = new UInt256(coin.AssetId),
                     Value = new Fixed8(coin.Value),
                     ScriptHash = new UInt160(coin.ScriptHash),
                     addr = GetContract(new UInt160(coin.ScriptHash)).paymentAddress,
                     r = new UInt256(coin.r),
                     rho = new UInt256(coin.rho),
                     witness = coin.Witness,
                     witness_height = coin.WitnessHeight
                 },
                 State = coin.State
             });
         }
     }
 }
Beispiel #10
0
 private void OnCreateAccount(WalletKeyPair account)
 {
     byte[] decryptedPrivateKey = new byte[96];
     Buffer.BlockCopy(account.PublicKey.EncodePoint(false), 1, decryptedPrivateKey, 0, 64);
     using (account.Decrypt())
     {
         Buffer.BlockCopy(account.PrivateKey, 0, decryptedPrivateKey, 64, 32);
     }
     byte[] encryptedPrivateKey = EncryptPrivateKey(decryptedPrivateKey);
     Array.Clear(decryptedPrivateKey, 0, decryptedPrivateKey.Length);
     using (WalletDataContext ctx = new WalletDataContext(DbPath))
     {
         Account db_account = ctx.Accounts.FirstOrDefault(p => p.PublicKeyHash.SequenceEqual(account.PublicKeyHash.ToArray()));
         if (db_account == null)
         {
             db_account = ctx.Accounts.Add(new Account
             {
                 PrivateKeyEncrypted = encryptedPrivateKey,
                 PublicKeyHash       = account.PublicKeyHash.ToArray()
             }).Entity;
         }
         else
         {
             db_account.PrivateKeyEncrypted = encryptedPrivateKey;
         }
         ctx.SaveChanges();
     }
 }
Beispiel #11
0
        public override bool DeleteAddress(UInt160 scriptHash)
        {
            bool flag = base.DeleteAddress(scriptHash);

            if (flag)
            {
                using (WalletDataContext ctx = new WalletDataContext(DbPath))
                {
                    Address address = ctx.Addresses.FirstOrDefault(p => p.ScriptHash.SequenceEqual(scriptHash.ToArray()));
                    if (address != null)
                    {
                        ctx.Addresses.Remove(address);
                        try
                        {
                            ctx.SaveChanges();
                        }
                        catch (Exception ex)
                        {
                            string str = ex.Message;
                        }
                    }
                }
            }
            return(flag);
        }
Beispiel #12
0
 protected override void BuildDatabase()
 {
     using (WalletDataContext ctx = new WalletDataContext(DbPath))
     {
         ctx.Database.EnsureDeleted();
         ctx.Database.EnsureCreated();
     }
 }
Beispiel #13
0
 protected override void SaveStoredData(string name, byte[] value)
 {
     using (WalletDataContext ctx = new WalletDataContext(DbPath))
     {
         SaveStoredData(ctx, name, value);
         ctx.SaveChanges();
     }
 }
Beispiel #14
0
 protected override IEnumerable <UInt160> LoadWatchOnly()
 {
     using (WalletDataContext ctx = new WalletDataContext(DbPath))
     {
         foreach (byte[] hash in ctx.Addresses.Where(p => !ctx.Contracts.Select(q => q.ScriptHash).Contains(p.ScriptHash)).Select(p => p.ScriptHash))
         {
             yield return(new UInt160(hash));
         }
     }
 }
Beispiel #15
0
 protected override IEnumerable <VerificationContract> LoadContracts()
 {
     using (WalletDataContext ctx = new WalletDataContext(DbPath))
     {
         foreach (Contract contract in ctx.Contracts)
         {
             yield return(contract.RawData.AsSerializable <VerificationContract>());
         }
     }
 }
Beispiel #16
0
        private void OnCreateAccount(StealthKeyPair account)
        {
            byte[] decryptedPayloadPrivKey = new byte[96];
            Buffer.BlockCopy(account.PayloadPubKey.EncodePoint(false), 1, decryptedPayloadPrivKey, 0, 64);

            using (account.DecryptPayloadKey())
            {
                Buffer.BlockCopy(account.PayloadPrivKey, 0, decryptedPayloadPrivKey, 64, 32);
            }
            byte[] encryptedPayloadPrivKey = EncryptPrivateKey(decryptedPayloadPrivKey);
            Array.Clear(decryptedPayloadPrivKey, 0, decryptedPayloadPrivKey.Length);

            byte[] decryptedViewPrivKey = new byte[96];
            Buffer.BlockCopy(account.ViewPubKey.EncodePoint(false), 1, decryptedViewPrivKey, 0, 64);

            using (account.DecryptViewKey())
            {
                Buffer.BlockCopy(account.ViewPrivKey, 0, decryptedViewPrivKey, 64, 32);
            }
            byte[] encryptedViewPrivKey = EncryptPrivateKey(decryptedViewPrivKey);
            Array.Clear(decryptedViewPrivKey, 0, decryptedViewPrivKey.Length);

            using (WalletDataContext ctx = new WalletDataContext(DbPath))
            {
                Account db_account = ctx.Accounts.FirstOrDefault(p => p.PublicKeyHash.SequenceEqual(account.PublicKeyHash.ToArray()));
                if (db_account == null)
                {
                    db_account = ctx.Accounts.Add(new Account
                    {
                        nVersion                = (int)account.nVersion,
                        PrivateKeyEncrypted     = encryptedPayloadPrivKey,
                        PublicKeyHash           = account.PublicKeyHash.ToArray(),
                        PrivateViewKeyEncrypted = encryptedViewPrivKey
                    }).Entity;
                }
                else
                {
                    db_account.nVersion                = (int)account.nVersion;
                    db_account.PrivateKeyEncrypted     = encryptedPayloadPrivKey;
                    db_account.PrivateViewKeyEncrypted = encryptedViewPrivKey;
                }

                try
                {
                    ctx.SaveChanges();
                }
                catch (Exception ex)
                {
                    string str = ex.Message;
                }
            }
        }
Beispiel #17
0
 public override IEnumerable <T> GetTransactions <T>()
 {
     using (WalletDataContext ctx = new WalletDataContext(DbPath))
     {
         IQueryable <Transaction> transactions = ctx.Transactions;
         if (typeof(T).GetTypeInfo().IsSubclassOf(typeof(CoreTransaction)))
         {
             TransactionType type = (TransactionType)Enum.Parse(typeof(TransactionType), typeof(T).Name);
             transactions = transactions.Where(p => p.Type == type);
         }
         return(transactions.Select(p => p.RawData).ToArray().Select(p => (T)CoreTransaction.DeserializeFrom(p)));
     }
 }
Beispiel #18
0
 protected override IEnumerable <WalletKeyPair> LoadKeyPairs()
 {
     using (WalletDataContext ctx = new WalletDataContext(DbPath))
     {
         foreach (byte[] encryptedPrivateKey in ctx.Accounts.Select(p => p.PrivateKeyEncrypted))
         {
             byte[]        decryptedPrivateKey = DecryptPrivateKey(encryptedPrivateKey);
             WalletKeyPair account             = new WalletKeyPair(decryptedPrivateKey);
             Array.Clear(decryptedPrivateKey, 0, decryptedPrivateKey.Length);
             yield return(account);
         }
     }
 }
Beispiel #19
0
 protected override byte[] LoadStoredData(string name)
 {
     using (WalletDataContext ctx = new WalletDataContext(DbPath))
     {
         try
         {
             return(ctx.Keys.FirstOrDefault(p => p.Name == name)?.Value);
         }
         catch
         {
             throw new FormatException("Wallet is not correct");
         }
     }
 }
Beispiel #20
0
        protected override void OnSaveTransaction(CoreTransaction tx,
                                                  IEnumerable <WalletCoin> added,
                                                  IEnumerable <WalletCoin> changed,
                                                  IEnumerable <JSWalletCoin> jsadded,
                                                  IEnumerable <JSWalletCoin> jschanged,
                                                  IEnumerable <JSWalletCoin> jsdeleted,
                                                  IEnumerable <JSWalletCoin> jswitnesschanged,
                                                  IEnumerable <RCTWalletCoin> rctadded,
                                                  IEnumerable <RCTWalletCoin> rctchanged,
                                                  IEnumerable <RCTWalletCoin> rctdeleted)
        {
            Transaction tx_changed = null;

            using (WalletDataContext ctx = new WalletDataContext(DbPath))
            {
                if (IsWalletTransaction(tx))
                {
                    tx_changed = ctx.Transactions.Add(new Transaction
                    {
                        Hash    = tx.Hash.ToArray(),
                        Type    = tx.Type,
                        RawData = tx.ToArray(),
                        Height  = null,
                        Time    = DateTime.Now
                    }).Entity;
                }
                OnCoinsChanged(ctx, added, changed, Enumerable.Empty <WalletCoin>(),
                               jsadded,
                               jschanged,
                               jsdeleted,
                               jswitnesschanged,
                               rctadded,
                               rctchanged,
                               rctdeleted);

                try
                {
                    ctx.SaveChanges();
                }
                catch (Exception ex)
                {
                    string str = ex.Message;
                }
            }
            if (tx_changed != null)
            {
                TransactionsChanged?.Invoke(this, GetTransactionInfo(new[] { tx_changed }));
            }
        }
Beispiel #21
0
 protected override void SaveStoredData(string name, byte[] value)
 {
     using (WalletDataContext ctx = new WalletDataContext(DbPath))
     {
         SaveStoredData(ctx, name, value);
         try
         {
             ctx.SaveChanges();
         }
         catch (Exception ex)
         {
             string str = ex.Message;
         }
     }
 }
Beispiel #22
0
 public override void AddWatchOnly(UInt160 scriptHash)
 {
     base.AddWatchOnly(scriptHash);
     using (WalletDataContext ctx = new WalletDataContext(DbPath))
     {
         if (ctx.Addresses.All(p => !p.ScriptHash.SequenceEqual(scriptHash.ToArray())))
         {
             ctx.Addresses.Add(new Address
             {
                 ScriptHash = scriptHash.ToArray()
             });
             ctx.SaveChanges();
         }
     }
 }
Beispiel #23
0
 public override void Rebuild()
 {
     lock (SyncRoot)
     {
         base.Rebuild();
         using (WalletDataContext ctx = new WalletDataContext(DbPath))
         {
             ctx.Keys.First(p => p.Name == "Height").Value = BitConverter.GetBytes(0);
             string str = nameof(Transaction);
             str = nameof(Coin);
             ctx.Database.ExecuteSqlCommand($"DELETE FROM [Transaction]"); //{nameof(Transaction)}
             ctx.Database.ExecuteSqlCommand($"DELETE FROM [Coin]");        //{nameof(Coin)}
             ctx.SaveChanges();
         }
     }
 }
Beispiel #24
0
        private static void SaveStoredData(WalletDataContext ctx, string name, byte[] value)
        {
            Key key = ctx.Keys.FirstOrDefault(p => p.Name == name);

            if (key == null)
            {
                ctx.Keys.Add(new Key
                {
                    Name  = name,
                    Value = value
                });
            }
            else
            {
                key.Value = value;
            }
        }
Beispiel #25
0
        public static Version GetVersion(string path)
        {
            byte[] buffer;
            using (WalletDataContext ctx = new WalletDataContext(path))
            {
                buffer = ctx.Keys.FirstOrDefault(p => p.Name == "Version")?.Value;
            }
            if (buffer == null)
            {
                return(new Version(0, 0));
            }
            int major    = buffer.ToInt32(0);
            int minor    = buffer.ToInt32(4);
            int build    = buffer.ToInt32(8);
            int revision = buffer.ToInt32(12);

            return(new Version(major, minor, build, revision));
        }
Beispiel #26
0
 protected override void OnProcessNewBlock(Block block, IEnumerable <WalletCoin> added, IEnumerable <WalletCoin> changed, IEnumerable <WalletCoin> deleted)
 {
     Transaction[] tx_changed = null;
     using (WalletDataContext ctx = new WalletDataContext(DbPath))
     {
         foreach (CoreTransaction tx in block.Transactions.Where(p => IsWalletTransaction(p)))
         {
             Transaction db_tx = ctx.Transactions.FirstOrDefault(p => p.Hash.SequenceEqual(tx.Hash.ToArray()));
             if (db_tx == null)
             {
                 ctx.Transactions.Add(new Transaction
                 {
                     Hash    = tx.Hash.ToArray(),
                     Type    = tx.Type,
                     RawData = tx.ToArray(),
                     Height  = block.Index,
                     Time    = block.Timestamp.ToDateTime()
                 });
             }
             else
             {
                 db_tx.Height = block.Index;
             }
         }
         OnCoinsChanged(ctx, added, changed, deleted);
         if (block.Index == Blockchain.Default.Height || ctx.ChangeTracker.Entries().Any())
         {
             foreach (Transaction db_tx in ctx.Transactions.Where(p => !p.Height.HasValue))
             {
                 if (block.Transactions.Any(p => p.Hash == new UInt256(db_tx.Hash)))
                 {
                     db_tx.Height = block.Index;
                 }
             }
             ctx.Keys.First(p => p.Name == "Height").Value = BitConverter.GetBytes(WalletHeight);
             tx_changed = ctx.ChangeTracker.Entries <Transaction>().Where(p => p.State != EntityState.Unchanged).Select(p => p.Entity).ToArray();
             ctx.SaveChanges();
         }
     }
     if (tx_changed?.Length > 0)
     {
         TransactionsChanged?.Invoke(this, GetTransactionInfo(tx_changed));
     }
 }
Beispiel #27
0
        public static void Migrate(string path_old, string path_new)
        {
            Version current_version = typeof(UserWallet).GetTypeInfo().Assembly.GetName().Version;

            using (WalletDataContext ctx_old = new WalletDataContext(path_old))
                using (WalletDataContext ctx_new = new WalletDataContext(path_new))
                {
                    ctx_new.Database.EnsureCreated();
                    ctx_new.Accounts.AddRange(ctx_old.Accounts);
                    ctx_new.Addresses.AddRange(ctx_old.Contracts.Select(p => new Address {
                        ScriptHash = p.ScriptHash
                    }));
                    ctx_new.Contracts.AddRange(ctx_old.Contracts);
                    ctx_new.Keys.AddRange(ctx_old.Keys.Where(p => p.Name != "Height" && p.Name != "Version"));
                    SaveStoredData(ctx_new, "Height", new byte[sizeof(int)]);
                    SaveStoredData(ctx_new, "Version", new[] { current_version.Major, current_version.Minor, current_version.Build, current_version.Revision }.Select(p => BitConverter.GetBytes(p)).SelectMany(p => p).ToArray());
                    ctx_new.SaveChanges();
                }
        }
Beispiel #28
0
 private void OnCoinsChanged(WalletDataContext ctx, IEnumerable <WalletCoin> added, IEnumerable <WalletCoin> changed, IEnumerable <WalletCoin> deleted)
 {
     foreach (WalletCoin coin in added)
     {
         ctx.Coins.Add(new Coin
         {
             TxId       = coin.Reference.PrevHash.ToArray(),
             Index      = coin.Reference.PrevIndex,
             AssetId    = coin.Output.AssetId.ToArray(),
             Value      = coin.Output.Value.GetData(),
             ScriptHash = coin.Output.ScriptHash.ToArray(),
             State      = coin.State
         });
     }
     foreach (WalletCoin coin in changed)
     {
         ctx.Coins.First(p => p.TxId.SequenceEqual(coin.Reference.PrevHash.ToArray()) && p.Index == coin.Reference.PrevIndex).State = coin.State;
     }
     foreach (WalletCoin coin in deleted)
     {
         Coin unspent_coin = ctx.Coins.FirstOrDefault(p => p.TxId.SequenceEqual(coin.Reference.PrevHash.ToArray()) && p.Index == coin.Reference.PrevIndex);
         ctx.Coins.Remove(unspent_coin);
     }
 }
Beispiel #29
0
 protected override IEnumerable <WalletCoin> LoadCoins()
 {
     using (WalletDataContext ctx = new WalletDataContext(DbPath))
     {
         foreach (Coin coin in ctx.Coins)
         {
             yield return(new WalletCoin
             {
                 Reference = new CoinReference
                 {
                     PrevHash = new UInt256(coin.TxId),
                     PrevIndex = coin.Index
                 },
                 Output = new TransactionOutput
                 {
                     AssetId = new UInt256(coin.AssetId),
                     Value = new Fixed8(coin.Value),
                     ScriptHash = new UInt160(coin.ScriptHash),
                 },
                 State = coin.State
             });
         }
     }
 }
Beispiel #30
0
        private void OnCoinsChanged(WalletDataContext ctx,
                                    IEnumerable <WalletCoin> added,
                                    IEnumerable <WalletCoin> changed,
                                    IEnumerable <WalletCoin> deleted,
                                    IEnumerable <JSWalletCoin> jsadded,
                                    IEnumerable <JSWalletCoin> jschanged,
                                    IEnumerable <JSWalletCoin> jsdeleted,
                                    IEnumerable <JSWalletCoin> jswitnesschanged,
                                    IEnumerable <RCTWalletCoin> rctadded,
                                    IEnumerable <RCTWalletCoin> rctchanged,
                                    IEnumerable <RCTWalletCoin> rctdeleted)
        {
            #region Transparent Coin
            foreach (WalletCoin coin in added)
            {
                try
                {
                    ctx.Coins.Add(new Coin
                    {
                        TxId       = coin.Reference.PrevHash.ToArray(),
                        Index      = coin.Reference.PrevIndex,
                        AssetId    = coin.Output.AssetId.ToArray(),
                        Value      = coin.Output.Value.GetData(),
                        ScriptHash = coin.Output.ScriptHash.ToArray(),
                        State      = coin.State
                    });
                    ctx.SaveChanges();
                }
                catch (Exception)
                {
                }
            }
            foreach (WalletCoin coin in changed)
            {
                ctx.Coins.First(p => p.TxId.SequenceEqual(coin.Reference.PrevHash.ToArray()) && p.Index == coin.Reference.PrevIndex).State = coin.State;
                try
                {
                    ctx.Coins.Update(ctx.Coins.First(p => p.TxId.SequenceEqual(coin.Reference.PrevHash.ToArray()) && p.Index == coin.Reference.PrevIndex));
                    ctx.SaveChanges();
                }
                catch (Exception)
                {
                }
            }
            foreach (WalletCoin coin in deleted)
            {
                try
                {
                    Coin unspent_coin = ctx.Coins.FirstOrDefault(p => p.TxId.SequenceEqual(coin.Reference.PrevHash.ToArray()) && p.Index == coin.Reference.PrevIndex);
                    ctx.Coins.Remove(unspent_coin);
                    ctx.SaveChanges();
                }
                catch (Exception)
                {
                }
            }
            #endregion

            #region ZK-SNARKS Coin
            foreach (JSWalletCoin coin in jsadded)
            {
                ctx.JSCoins.Add(new JSCoin
                {
                    TxId          = coin.Reference.PrevHash.ToArray(),
                    JsId          = coin.Reference.PrevJsId,
                    Index         = coin.Reference.PrevIndex,
                    AssetId       = coin.Output.AssetId.ToArray(),
                    Value         = coin.Output.Value.GetData(),
                    ScriptHash    = coin.Output.ScriptHash.ToArray(),
                    State         = coin.State,
                    r             = coin.Output.r.ToArray(),
                    rho           = coin.Output.rho.ToArray(),
                    Witness       = coin.Output.witness,
                    WitnessHeight = coin.Output.witness_height,
                    CMTreeHeight  = coin.Output.cmtree_height
                });

                try
                {
                    ctx.SaveChanges();
                }
                catch (Exception ex)
                {
                    string error = ex.Message;
                }
            }
            foreach (JSWalletCoin coin in jschanged)
            {
                ctx.JSCoins.First(p => p.TxId.SequenceEqual(coin.Reference.PrevHash.ToArray()) && p.Index == coin.Reference.PrevIndex && p.JsId == coin.Reference.PrevJsId).State         = coin.State;
                ctx.JSCoins.First(p => p.TxId.SequenceEqual(coin.Reference.PrevHash.ToArray()) && p.Index == coin.Reference.PrevIndex && p.JsId == coin.Reference.PrevJsId).Witness       = coin.Output.witness;
                ctx.JSCoins.First(p => p.TxId.SequenceEqual(coin.Reference.PrevHash.ToArray()) && p.Index == coin.Reference.PrevIndex && p.JsId == coin.Reference.PrevJsId).WitnessHeight = coin.Output.witness_height;
                ctx.JSCoins.First(p => p.TxId.SequenceEqual(coin.Reference.PrevHash.ToArray()) && p.Index == coin.Reference.PrevIndex && p.JsId == coin.Reference.PrevJsId).CMTreeHeight  = coin.Output.cmtree_height;
                try
                {
                    ctx.SaveChanges();
                }
                catch (Exception ex)
                {
                    string error = ex.Message;
                }
            }
            foreach (JSWalletCoin coin in jsdeleted)
            {
                JSCoin unspent_coin = ctx.JSCoins.FirstOrDefault(p => p.TxId.SequenceEqual(coin.Reference.PrevHash.ToArray()) && p.Index == coin.Reference.PrevIndex && p.JsId == coin.Reference.PrevJsId);
                ctx.JSCoins.Remove(unspent_coin);
            }
            foreach (JSWalletCoin coin in jswitnesschanged)
            {
                JSCoin update_coin = ctx.JSCoins.FirstOrDefault(p => p.TxId.SequenceEqual(coin.Reference.PrevHash.ToArray()) && p.Index == coin.Reference.PrevIndex && p.JsId == coin.Reference.PrevJsId);
                if (update_coin != null)
                {
                    try
                    {
                        update_coin.Witness       = coin.Output.witness;
                        update_coin.WitnessHeight = coin.Output.witness_height;
                        ctx.JSCoins.Update(update_coin);
                        ctx.SaveChanges();
                    }
                    catch (Exception ex)
                    {
                        string error = ex.Message;
                    }
                }
            }
            #endregion

            #region RingCT Coin
            foreach (RCTWalletCoin coin in rctadded)
            {
                ctx.RCTCoins.Add(new RCTCoin
                {
                    TxId       = coin.Reference.PrevHash.ToArray(),
                    TxRCTHash  = coin.Reference.TxRCTHash.ToArray(),
                    RctID      = coin.Reference.PrevRCTSigId,
                    Index      = coin.Reference.PrevRCTSigIndex,
                    AssetId    = coin.Output.AssetId.ToArray(),
                    Value      = coin.Output.Value.GetData(),
                    PubKey     = coin.Output.PubKey.ToArray(),
                    ScriptHash = coin.Output.ScriptHash.ToArray(),
                    State      = coin.State
                });

                try
                {
                    ctx.SaveChanges();
                }
                catch (Exception ex)
                {
                    string error = ex.Message;
                }
            }

            foreach (RCTWalletCoin coin in rctchanged)
            {
                ctx.RCTCoins.First(p => p.TxRCTHash.SequenceEqual(coin.Reference.TxRCTHash.ToArray()) && p.RctID == coin.Reference.PrevRCTSigId && p.Index == coin.Reference.PrevRCTSigIndex).State = coin.State;

                try
                {
                    ctx.SaveChanges();
                }
                catch (Exception ex)
                {
                    string error = ex.Message;
                }
            }

            foreach (RCTWalletCoin coin in rctdeleted)
            {
                RCTCoin unspent_coin = ctx.RCTCoins.FirstOrDefault(p => p.TxId.SequenceEqual(coin.Reference.PrevHash.ToArray()) && p.RctID == coin.Reference.PrevRCTSigId && p.Index == coin.Reference.PrevRCTSigIndex);
                ctx.RCTCoins.Remove(unspent_coin);
            }
            #endregion
        }