示例#1
0
        private void ValidateTransfersAddresses(string seed, int security, List <string> trytes)
        {
            HashSet <string>   addresses         = new HashSet <string>();
            List <Transaction> inputTransactions = new List <Transaction>();
            List <string>      inputAddresses    = new List <string>();


            foreach (var trx in trytes)
            {
                addresses.Add(new Transaction(trx).Address);
                inputTransactions.Add(new Transaction(trx));
            }

            var hashes = IotaClient.FindTransactionsByAddresses(addresses.ToArray()).Hashes;
            List <Transaction> transactions = FindTransactionObjectsByHashes(hashes.ToArray());

            // Get addresses until first unspent
            var addressRequest = new AddressRequest(seed, security)
            {
                Amount = 0, Checksum = true
            };
            var gna = GenerateNewAddresses(addressRequest);

            // Get inputs for this seed, until we fund an unused address
            var gbr = GetInputs(seed, security, 0, 0, 0);

            foreach (var input in gbr.Inputs)
            {
                inputAddresses.Add(input.Address);
            }

            //check if send to input
            foreach (var trx in inputTransactions)
            {
                if (trx.Value > 0 && inputAddresses.Contains(trx.Address))
                {
                    throw new ArgumentException("Send to inputs!");
                }
            }

            foreach (var trx in transactions)
            {
                //check if destination address is already in use
                if (trx.Value < 0 && !inputAddresses.Contains(trx.Address))
                {
                    throw new ArgumentException("Sending to a used address.");
                }

                //check if key reuse
                if (trx.Value < 0 && gna.Addresses.Contains(trx.Address))
                {
                    throw new ArgumentException("Private key reuse detect!");
                }
            }
        }
示例#2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="addresses"></param>
        /// <returns></returns>
        public List <Transaction> FindTransactionObjectsByAddresses(string[] addresses)
        {
            var ftr = IotaClient.FindTransactionsByAddresses(addresses);

            if (ftr?.Hashes == null)
            {
                return(new List <Transaction>());
            }

            // get the transaction objects of the transactions
            return(FindTransactionObjectsByHashes(ftr.Hashes.ToArray()));
        }
示例#3
0
        private bool IsAddressSpent(string newAddress, bool checksum)
        {
            string address  = checksum ? newAddress : newAddress.AddChecksum();
            var    response = IotaClient.FindTransactionsByAddresses(address);

            if (response.Hashes.Count == 0)
            {
                var spentFromResponse = IotaClient.WereAddressesSpentFrom(address);
                return(spentFromResponse.States[0]);
            }

            return(true);
        }
示例#4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="seed"></param>
        /// <param name="security"></param>
        /// <param name="start"></param>
        /// <param name="end"></param>
        /// <param name="threshold"></param>
        /// <param name="tips"></param>
        /// <returns></returns>
        public GetBalancesAndFormatResponse GetInputs(string seed, int security, int start, int end, long threshold,
                                                      params string[] tips)
        {
            // validate the seed
            if (!InputValidator.IsValidSeed(seed))
            {
                throw new IllegalStateException(Constants.INVALID_SEED_INPUT_ERROR);
            }

            seed = InputValidator.PadSeedIfNecessary(seed);

            if (!InputValidator.IsValidSecurityLevel(security))
            {
                throw new ArgumentException(Constants.INVALID_SECURITY_LEVEL_INPUT_ERROR);
            }

            // If start value bigger than end, return error
            if (start > end)
            {
                throw new ArgumentException("start must be smaller than end", nameof(start));
            }

            // or if difference between end and start is bigger than 500 keys
            if (end - start > 500)
            {
                throw new ArgumentException("total number of keys exceeded 500");
            }


            Stopwatch stopwatch = Stopwatch.StartNew();

            //  Case 1: start and end
            //
            //  If start and end is defined by the user, simply iterate through the keys
            //  and call getBalances
            if (end != 0)
            {
                var allAddresses = new string[end - start];

                for (var i = start; i < end; i++)
                {
                    var address = IotaApiUtils.NewAddress(seed, security, i, true,
                                                          SpongeFactory.Create(SpongeFactory.Mode.KERL));
                    allAddresses[i] = address;
                }

                return(GetBalanceAndFormat(allAddresses, tips, threshold, start, security, stopwatch));
            }

            {
                //  Case 2: iterate till threshold
                //
                //  Either start from index: 0 or start (if defined) until threshold is reached.
                List <Input> allInputs = new List <Input>();

                bool thresholdReached = true;
                long currentTotal     = 0;

                for (int i = start; thresholdReached; i++)
                {
                    string address = IotaApiUtils.NewAddress(seed, security, i, true,
                                                             SpongeFactory.Create(SpongeFactory.Mode.KERL));

                    // Received input, this epoch or previous
                    GetBalancesResponse response =
                        IotaClient.GetBalances(100, new List <string>()
                    {
                        address
                    }, tips.ToList());
                    var balance = response.Balances[0];

                    if (balance > 0)
                    {
                        // Is it already spent from?
                        WereAddressesSpentFromResponse wasSpent = IotaClient.WereAddressesSpentFrom(address);
                        if (wasSpent.States.Length > 0 && !wasSpent.States[0])
                        {
                            // We can use this!
                            allInputs.Add(new Input
                            {
                                Address = address, Balance = balance, KeyIndex = i, Security = security
                            });
                            currentTotal += balance;

                            if (threshold != 0 && threshold <= currentTotal)
                            {
                                // Stop because we found threshold
                                thresholdReached = false;
                            }
                        }
                    }
                    else
                    {
                        // Check if there was any activity at all
                        FindTransactionsResponse tx = IotaClient.FindTransactionsByAddresses(address);
                        if (tx.Hashes.Count == 0 || i - start > 500)
                        {
                            // Stop because we reached our limit or no activity
                            thresholdReached = false;
                        }
                    }
                }

                stopwatch.Stop();
                return(new GetBalancesAndFormatResponse(allInputs, currentTotal, stopwatch.ElapsedMilliseconds));
            }
        }