예제 #1
0
 public bool SaveTransaction(Transaction tx)
 {
     Coin[] changeset;
     lock (contracts)
         lock (coins)
         {
             if (tx.GetAllInputs().Any(p => !coins.Contains(p) || coins[p].State != CoinState.Unspent))
             {
                 return(false);
             }
             foreach (TransactionInput input in tx.GetAllInputs())
             {
                 coins[input].State = CoinState.Spending;
             }
             for (ushort i = 0; i < tx.Outputs.Length; i++)
             {
                 if (contracts.ContainsKey(tx.Outputs[i].ScriptHash))
                 {
                     coins.Add(new Coin
                     {
                         Input = new TransactionInput
                         {
                             PrevHash  = tx.Hash,
                             PrevIndex = i
                         },
                         AssetId    = tx.Outputs[i].AssetId,
                         Value      = tx.Outputs[i].Value,
                         ScriptHash = tx.Outputs[i].ScriptHash,
                         State      = CoinState.Unconfirmed
                     });
                 }
             }
             changeset = coins.GetChangeSet();
             OnSaveTransaction(tx, changeset.Where(p => ((ITrackable <TransactionInput>)p).TrackState == TrackState.Added), changeset.Where(p => ((ITrackable <TransactionInput>)p).TrackState == TrackState.Changed));
             coins.Commit();
         }
     if (changeset.Length > 0)
     {
         BalanceChanged?.Invoke(this, EventArgs.Empty);
     }
     return(true);
 }
예제 #2
0
 private void WalletIndexer_BalanceChanged(object sender, BalanceEventArgs e)
 {
     lock (unconfirmed)
     {
         unconfirmed.Remove(e.Transaction.Hash);
     }
     UInt160[] relatedAccounts;
     lock (accounts)
     {
         relatedAccounts = e.RelatedAccounts.Where(p => accounts.ContainsKey(p)).ToArray();
     }
     if (relatedAccounts.Length > 0)
     {
         BalanceChanged?.Invoke(this, new BalanceEventArgs
         {
             Transaction     = e.Transaction,
             RelatedAccounts = relatedAccounts,
             Height          = e.Height,
             Time            = e.Time
         });
     }
 }
예제 #3
0
 private void ProcessNewBlock(Block block)
 {
     Coin[] changeset;
     lock (contracts)
         lock (coins)
         {
             foreach (Transaction tx in block.Transactions)
             {
                 for (ushort index = 0; index < tx.Outputs.Length; index++)
                 {
                     TransactionOutput output = tx.Outputs[index];
                     AddressState      state  = CheckAddressState(output.ScriptHash);
                     if (state.HasFlag(AddressState.InWallet))
                     {
                         CoinReference key = new CoinReference
                         {
                             PrevHash  = tx.Hash,
                             PrevIndex = index
                         };
                         if (coins.Contains(key))
                         {
                             coins[key].State |= CoinState.Confirmed;
                         }
                         else
                         {
                             coins.Add(new Coin
                             {
                                 Reference = key,
                                 Output    = output,
                                 State     = CoinState.Confirmed
                             });
                         }
                         if (state.HasFlag(AddressState.WatchOnly))
                         {
                             coins[key].State |= CoinState.WatchOnly;
                         }
                     }
                 }
             }
             foreach (Transaction tx in block.Transactions)
             {
                 foreach (CoinReference input in tx.Inputs)
                 {
                     if (coins.Contains(input))
                     {
                         if (coins[input].Output.AssetId.Equals(Blockchain.SystemShare.Hash))
                         {
                             coins[input].State |= CoinState.Spent | CoinState.Confirmed;
                         }
                         else
                         {
                             coins.Remove(input);
                         }
                     }
                 }
             }
             foreach (ClaimTransaction tx in block.Transactions.OfType <ClaimTransaction>())
             {
                 foreach (CoinReference claim in tx.Claims)
                 {
                     if (coins.Contains(claim))
                     {
                         coins.Remove(claim);
                     }
                 }
             }
             current_height++;
             changeset = coins.GetChangeSet();
             OnProcessNewBlock(block, changeset.Where(p => ((ITrackable <CoinReference>)p).TrackState == TrackState.Added), changeset.Where(p => ((ITrackable <CoinReference>)p).TrackState == TrackState.Changed), changeset.Where(p => ((ITrackable <CoinReference>)p).TrackState == TrackState.Deleted));
             coins.Commit();
         }
     if (changeset.Length > 0)
     {
         BalanceChanged?.Invoke(this, EventArgs.Empty);
     }
 }
예제 #4
0
 protected virtual void OnBalanceChanged()
 {
     BalanceChanged?.Invoke(this, EventArgs.Empty);
 }
예제 #5
0
 private static void balanceChangedHandler(int balance)
 {
     BalanceChanged?.Invoke(account, new AccountEventArgs(balance));
 }
예제 #6
0
 private static void ProcessBlock(Block block, HashSet <UInt160> accounts, WriteBatch batch)
 {
     foreach (Transaction tx in block.Transactions)
     {
         HashSet <UInt160> accounts_changed = new HashSet <UInt160>();
         for (ushort index = 0; index < tx.Outputs.Length; index++)
         {
             TransactionOutput output = tx.Outputs[index];
             if (accounts_tracked.ContainsKey(output.ScriptHash))
             {
                 CoinReference reference = new CoinReference
                 {
                     PrevHash  = tx.Hash,
                     PrevIndex = index
                 };
                 if (coins_tracked.TryGetValue(reference, out Coin coin))
                 {
                     coin.State |= CoinState.Confirmed;
                 }
                 else
                 {
                     accounts_tracked[output.ScriptHash].Add(reference);
                     coins_tracked.Add(reference, coin = new Coin
                     {
                         Reference = reference,
                         Output    = output,
                         State     = CoinState.Confirmed
                     });
                 }
                 batch.Put(SliceBuilder.Begin(DataEntryPrefix.ST_Coin).Add(reference), SliceBuilder.Begin().Add(output).Add((byte)coin.State));
                 accounts_changed.Add(output.ScriptHash);
             }
         }
         foreach (CoinReference input in tx.Inputs)
         {
             if (coins_tracked.TryGetValue(input, out Coin coin))
             {
                 if (coin.Output.AssetId.Equals(Blockchain.GoverningToken.Hash))
                 {
                     coin.State |= CoinState.Spent | CoinState.Confirmed;
                     batch.Put(SliceBuilder.Begin(DataEntryPrefix.ST_Coin).Add(input), SliceBuilder.Begin().Add(coin.Output).Add((byte)coin.State));
                 }
                 else
                 {
                     accounts_tracked[coin.Output.ScriptHash].Remove(input);
                     coins_tracked.Remove(input);
                     batch.Delete(DataEntryPrefix.ST_Coin, input);
                 }
                 accounts_changed.Add(coin.Output.ScriptHash);
             }
         }
         if (tx is ClaimTransaction ctx)
         {
             foreach (CoinReference claim in ctx.Claims)
             {
                 if (coins_tracked.TryGetValue(claim, out Coin coin))
                 {
                     accounts_tracked[coin.Output.ScriptHash].Remove(claim);
                     coins_tracked.Remove(claim);
                     batch.Delete(DataEntryPrefix.ST_Coin, claim);
                     accounts_changed.Add(coin.Output.ScriptHash);
                 }
             }
         }
         if (accounts_changed.Count > 0)
         {
             foreach (UInt160 account in accounts_changed)
             {
                 batch.Put(SliceBuilder.Begin(DataEntryPrefix.ST_Transaction).Add(account).Add(tx.Hash), false);
             }
             BalanceChanged?.Invoke(null, new BalanceEventArgs
             {
                 Transaction     = tx,
                 RelatedAccounts = accounts_changed.ToArray(),
                 Height          = block.Index,
                 Time            = block.Timestamp
             });
         }
     }
 }
예제 #7
0
 private void OnBalanceChanged()
 {
     BalanceChanged?.Invoke(Balance);
 }
예제 #8
0
 public void Subscribe(BalanceChanged type)
 {
     CurrentBalance = type.CurrentBalance;
 }
예제 #9
0
 // Генерируем собтие при изменении баланса
 private void OnBalanceChange(double Balance)
 {
     BalanceChanged?.Invoke(new BalanceEventArgs(Balance));
 }
예제 #10
0
 public void ReduceAccountBalance(int id, double sum)
 {
     Accounts.Find(x => x.AccountID == id).Balance -= sum;
     BalanceChanged?.Invoke();
 }
예제 #11
0
 public void Subscribe(BalanceChanged type)
 {
     CurrentBalance = type.CurrentBalance;
     _balanceChangedSubject.OnNext(type);
 }
예제 #12
0
 private void ProcessNewBlock(Block block)
 {
     Coin[] changeset;
     lock (contracts)
         lock (coins)
         {
             foreach (Transaction tx in block.Transactions)
             {
                 for (ushort index = 0; index < tx.Outputs.Length; index++)
                 {
                     TransactionOutput output = tx.Outputs[index];
                     if (contracts.ContainsKey(output.ScriptHash))
                     {
                         TransactionInput key = new TransactionInput
                         {
                             PrevHash  = tx.Hash,
                             PrevIndex = index
                         };
                         if (coins.Contains(key))
                         {
                             coins[key].State = CoinState.Unspent;
                         }
                         else
                         {
                             coins.Add(new Coin
                             {
                                 Input      = key,
                                 AssetId    = output.AssetId,
                                 Value      = output.Value,
                                 ScriptHash = output.ScriptHash,
                                 State      = CoinState.Unspent
                             });
                         }
                     }
                 }
             }
             foreach (Transaction tx in block.Transactions)
             {
                 foreach (TransactionInput input in tx.GetAllInputs())
                 {
                     if (coins.Contains(input))
                     {
                         if (coins[input].AssetId == Blockchain.AntShare.Hash)
                         {
                             coins[input].State = CoinState.Spent;
                         }
                         else
                         {
                             coins.Remove(input);
                         }
                     }
                 }
             }
             foreach (ClaimTransaction tx in block.Transactions.OfType <ClaimTransaction>())
             {
                 foreach (TransactionInput claim in tx.Claims)
                 {
                     if (coins.Contains(claim))
                     {
                         coins.Remove(claim);
                     }
                 }
             }
             current_height++;
             changeset = coins.GetChangeSet();
             OnProcessNewBlock(block, changeset.Where(p => ((ITrackable <TransactionInput>)p).TrackState == TrackState.Added), changeset.Where(p => ((ITrackable <TransactionInput>)p).TrackState == TrackState.Changed), changeset.Where(p => ((ITrackable <TransactionInput>)p).TrackState == TrackState.Deleted));
             coins.Commit();
         }
     if (changeset.Length > 0)
     {
         BalanceChanged?.Invoke(this, EventArgs.Empty);
     }
 }
예제 #13
0
 protected virtual void OnBalanceChanged(List <AddressHistoryRecord> historyRecords)
 {
     BalanceChanged?.Invoke(this, new BalanceUpdateEventArgs {
         HistoryRecords = historyRecords
     });
 }
예제 #14
0
 public void Deposit(decimal amount)
 {
     Balance += amount;
     BalanceChanged?.Invoke(this, new BalanceChangedEventArg(BalanceChangeType.Deposit, amount));
 }
예제 #15
0
 private void Apply(BalanceChanged @event)
 {
     Balance += @event.Balance;
 }
예제 #16
0
 public void Deposit(int amount)
 {
     Balance += amount;
     WriteLine($"Deposited {amount}, balance is {Balance}");
     BalanceChanged?.Invoke(this, new AccountBalanceChangedEventArgs(Balance));
 }
예제 #17
0
        public BitcoinService(string baseAddress, ILoggerFactory loggerFactory)
        {
            _logger      = loggerFactory?.CreateLogger <BitcoinService>();
            _baseAddress = baseAddress;

            const string  walletFilePath = @"Wallets/hidden.dat";
            const string  password       = "******";
            const Network network        = Network.TestNet;

            KeyRing keyRing;
            string  mnemonic;

            if (!System.IO.File.Exists(walletFilePath))
            {
                keyRing = KeyRing.Create(out mnemonic, password, walletFilePath, network);
            }
            else
            {
                keyRing = KeyRing.Load(password, walletFilePath);
                if (keyRing.Network != network)
                {
                    throw new Exception("Wrong network");
                }
            }

            _httpKeyRingMonitor = new HttpKeyRingMonitor(_baseAddress, keyRing, addressCount: 100);

            // Report initialization progress
            _httpKeyRingMonitor.InitializationStateChanged += delegate(object sender, EventArgs args)
            {
                var monitor = (HttpKeyRingMonitor)sender;

                _logger.LogDebug($"state changed: {monitor.InitializationState}");

                InitializationState = monitor.InitializationState;
                InitializationStateChanged?.Invoke(null,
                                                   new BitcoinServiceArgs {
                    State = monitor.InitializationState
                });
            };

            _httpKeyRingMonitor.InitializationProgressPercentChanged += delegate(object sender, EventArgs args)
            {
                var monitor = (HttpKeyRingMonitor)sender;

                _logger.LogDebug($"progress changed: {monitor.InitializationProgressPercent}");

                InitializationProgress = monitor.InitializationProgressPercent;
                InitializationProgressChanged?.Invoke(null,
                                                      new BitcoinServiceArgs {
                    InitializationProgress = monitor.InitializationProgressPercent
                });
            };

            _httpKeyRingMonitor.BalanceChanged += delegate(object sender, EventArgs args)
            {
                var monitor   = (HttpKeyRingMonitor)sender;
                var arguments = (BalanceUpdateEventArgs)args;

                _logger.LogDebug($"Change happened\r\n" +
                                 $"Balance of safe: {monitor.KeyRingBalanceInfo.Balance}\r\n" +
                                 $"Confirmed balance of safe: {monitor.KeyRingBalanceInfo.Confirmed}\r\n" +
                                 $"Unconfirmed balance of safe: {monitor.KeyRingBalanceInfo.Unconfirmed}");

                BalanceChanged?.Invoke(null,
                                       new BitcoinServiceArgs {
                    BalanceInfo = monitor.KeyRingBalanceInfo, Transactions = arguments.HistoryRecords
                });
            };
        }
예제 #18
0
 public void IncreaseBalanceToAccount(int id, double sum)
 {
     Accounts.Find(x => x.AccountID == id).Balance += sum;
     BalanceChanged?.Invoke();
 }
예제 #19
0
 public void Add(int num)
 {
     have += num;
     BalanceChanged.Invoke("Add", new EventArgs());
 }