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 })); }
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 })); }