Ejemplo n.º 1
0
        public IActionResult GetAvailableInputs([FromBody] AvailableInputsRequest request)
        {
            var watch = System.Diagnostics.Stopwatch.StartNew();
            List <AddressUnspent> unspent = new List <AddressUnspent>();

            string selectString = @" EXEC Address_Available_Inputs  @Address";


            using (SqlConnection conn = new SqlConnection(connString))
            {
                using (SqlCommand comm = new SqlCommand(selectString, conn))
                {
                    comm.Parameters.AddWithValue("@Address", request.Address);

                    try
                    {
                        conn.Open();
                        using (SqlDataReader dr = comm.ExecuteReader())
                        {
                            unspent = DataReaderMapToList <AddressUnspent>(dr);
                        }
                    }
                    catch (Exception ex)
                    {
                        return(BadRequest(ex.ToErrorObject()));
                    }
                }
            }


            var memPool   = CoinService.GetRawMemPool(false);
            var memInputs = new List <string>();

            foreach (var item in memPool.TxIds)
            {
                memInputs.AddRange((CoinService.GetRawTransaction(item, 1).Vin).Select(t => t.TxId));
            }

            unspent = unspent.Where(u => !memInputs.Contains(u.Txid)).ToList();


            decimal fee    = 0.001m;
            var     newFee = (((unspent.Count * 148) + (2 * 34) + 10 + 9) / 1024m) * fee;

            if (newFee > fee)
            {
                fee = newFee;
            }

            fee = (decimal)RoundUp((double)fee, 3);


            if (unspent.Count == 0 && memInputs.Count > 0)
            {
                return(BadRequest(new Exception("Transactions being confirmed, please try again in one minute.").ToErrorObject()));
            }

            if (unspent.Sum(u => u.Value) < (request.Amount + fee))
            {
                return(BadRequest(new Exception("Amount exceeds the balance of [" + unspent.Sum(u => u.Value).ToString() + "]").ToErrorObject()));
            }

            List <AddressUnspent> data = new List <AddressUnspent>();

            foreach (var item in unspent)
            {
                data.Add(item);
                if (data.Sum(d => d.Value) >= request.Amount)
                {
                    break;
                }
            }

            fee    = 0.001m;
            newFee = (((data.Count * 148) + (2 * 34) + 10 + 9) / 1024m) * fee;
            if (newFee > fee)
            {
                fee = newFee;
            }


            fee = (decimal)RoundUp((double)fee, 3);

            string scriptPubKey = string.Empty;

            foreach (var item in data)
            {
                var raw = CoinService.GetRawTransaction(item.Txid, 1);

                foreach (var v in raw.Vout)
                {
                    if (Convert.ToDecimal(v.Value) == item.Value && v.ScriptPubKey.Addresses.ToList().Contains(item.Address))
                    {
                        scriptPubKey = v.ScriptPubKey.Hex;
                        break;
                    }
                }
                if (!string.IsNullOrEmpty(scriptPubKey))
                {
                    break;
                }
            }
            uint blockHeight = CoinService.GetBlockCount();

            watch.Stop();
            var elapsedMs = watch.ElapsedMilliseconds;


            return(new ObjectResult(new
            {
                BlockHeight = blockHeight,
                Fee = fee,
                ScriptPubKey = scriptPubKey,
                Inputs = data,
                Execution = elapsedMs
            }));
        }
Ejemplo n.º 2
0
        public IActionResult GetAvailableInputs([FromBody] AvailableInputsRequest request)
        {
            List <AddressUnspent> unspent = new List <AddressUnspent>();

            string selectString = @" SELECT Txid,
                                            [Index],
                                            Address,
                                            Value, 
                                            '' as ScriptPubKey 
                                       FROM [vAddressUnspent] 
                                      WHERE Address = @Address";


            using (SqlConnection conn = new SqlConnection(connString))
            {
                using (SqlCommand comm = new SqlCommand(selectString, conn))
                {
                    comm.Parameters.AddWithValue("@Address", request.Address);

                    try
                    {
                        conn.Open();
                        using (SqlDataReader dr = comm.ExecuteReader())
                        {
                            unspent = DataReaderMapToList <AddressUnspent>(dr);
                        }
                    }
                    catch (Exception ex)
                    {
                        return(BadRequest(ex.ToErrorObject()));
                    }
                }
            }

            decimal fee    = 0.001m;
            var     newFee = (((unspent.Count * 148) + (2 * 34) + 10 + 9) / 1024m) * fee;

            if (newFee > fee)
            {
                fee = newFee;
            }

            fee = (decimal)RoundUp((double)fee, 3);

            if (unspent.Sum(u => u.Value) < (request.Amount + fee))
            {
                return(BadRequest(new Exception("Amount exceeds the balance of [" + unspent.Sum(u => u.Value).ToString() + "]").ToErrorObject()));
            }

            List <AddressUnspent> data = new List <AddressUnspent>();

            foreach (var item in unspent.OrderByDescending(t => t.Value))
            {
                data.Add(item);
                if (data.Sum(d => d.Value) >= request.Amount)
                {
                    break;
                }
            }

            fee    = 0.001m;
            newFee = (((data.Count * 148) + (2 * 34) + 10 + 9) / 1024m) * fee;
            if (newFee > fee)
            {
                fee = newFee;
            }


            fee = (decimal)RoundUp((double)fee, 3);

            string scriptPubKey = string.Empty;

            foreach (var item in data)
            {
                var raw = CoinService.GetRawTransaction(item.Txid, 1);

                foreach (var v in raw.Vout)
                {
                    if (Convert.ToDecimal(v.Value) == item.Value && v.ScriptPubKey.Addresses.ToList().Contains(item.Address))
                    {
                        scriptPubKey = v.ScriptPubKey.Hex;
                        break;
                    }
                }
                if (!string.IsNullOrEmpty(scriptPubKey))
                {
                    break;
                }
            }

            return(new ObjectResult(new
            {
                Fee = fee,
                ScriptPubKey = scriptPubKey,
                Inputs = data
            }));
        }