/// <summary> /// Controller for the claim confirmation page, where users will /// review the claim and get instructions for signing. /// </summary> /// <param name="claimId"></param> /// <returns></returns> public ActionResult ClaimConfirm(string claimId) { try { CoinClaim userclaim = new CoinClaim(); using (CoinpanicContext db = new CoinpanicContext()) { userclaim = db.Claims.Where(c => c.ClaimId == claimId).Include(c => c.InputAddresses).AsNoTracking().First(); } ViewBag.Multiplier = BitcoinForks.ForkByShortName[userclaim.CoinShortName].Multiplier; //if (userclaim.CoinShortName == "BCH") //{ // // Convert // var depositAddress = SharpCashAddr.Converter.oldAddrToCashAddr(userclaim.DepositAddress, out bool isP2PKH, out _); // userclaim.DepositAddress = depositAddress; //} return(View(userclaim)); } catch { return(RedirectToAction("ClaimError", new { message = "claimId not valid", claimId = claimId })); } }
// GET: NewClaim public async Task <ActionResult> NewClaim(string coin, string coupon, string addresses) { string claimId = ShortId.Generate(useNumbers: false, useSpecial: false, length: 10); string ip = Request.UserHostAddress; List <string> addressList = addresses != null ? new List <string>( addresses.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries)) : new List <string>(); using (CoinpanicContext db = new CoinpanicContext()) { // Ensure the ClaimId is unique while (db.Claims.Where(c => c.ClaimId == claimId).Count() > 0) { claimId = ShortId.Generate(useNumbers: false, useSpecial: false, length: 10); } db.Claims.Add(new CoinClaim() { ClaimId = claimId, CoinShortName = coin, RequestIP = ip }); var res = db.SaveChanges(); var ci = db.IndexCoinInfo.Where(i => i.Coin == coin).AsNoTracking(); if (ci.Count() > 0) { ViewBag.Exchanges = ci.First().Exchanges.ToList(); } else { ViewBag.Exchanges = new List <Models.ExchangeInfo>(); } } // Make sure we understand how to sign the requested coin if (BitcoinForks.ForkByShortName.Keys.Contains(coin)) { var NewClaim = new CoinClaim { CoinShortName = coin, ClaimId = claimId }; List <InputAddress> inputs; inputs = GetInputAddresses(NewClaim, addressList); NewClaim.InputAddresses = inputs; return(View(NewClaim)); } else { return(RedirectToAction("InvalidCoin")); } }
public ActionResult InitializeClaim(string claimId, string PublicKeys, string depositAddress, string emailAddress) { using (CoinpanicContext db = new CoinpanicContext()) { CoinClaim userclaim = db.Claims.Where(c => c.ClaimId == claimId).Include(c => c.InputAddresses).First(); // Clean up input depositAddress = depositAddress.Replace("\n", String.Empty); depositAddress = depositAddress.Replace("\r", String.Empty); depositAddress = depositAddress.Replace("\t", String.Empty); depositAddress = depositAddress.Trim().Replace(" ", ""); userclaim.DepositAddress = depositAddress; userclaim.Email = emailAddress; List <string> list = new List <string>( PublicKeys.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries)); if (list.Count < 1) { return(RedirectToAction("ClaimError", new { message = "You must enter at least one address to claim", claimId = claimId })); } // Convert depositAddress if BCH if (userclaim.CoinShortName == "BCH" && depositAddress.StartsWith("bitcoincash:")) { // Convert depositAddress = SharpCashAddr.Converter.cashAddrToOldAddr(depositAddress, out bool isP2PKH, out _); } if (!Bitcoin.IsValidAddress(depositAddress, userclaim.CoinShortName, BitcoinForks.ForkByShortName[userclaim.CoinShortName].Network)) { return(RedirectToAction("ClaimError", new { message = "Deposit Address not valid", claimId = claimId })); } var invalid = list.Where(a => !Bitcoin.IsValidAddress(a)); if (invalid.Count() > 0) { return(RedirectToAction("ClaimError", new { message = String.Join(", ", invalid) + (invalid.Count() < 2 ? " is" : " are") + " invalid.", claimId = claimId })); } var scanner = new BlockScanner(); var claimAddresses = Bitcoin.ParseAddresses(list); Tuple <List <ICoin>, Dictionary <string, double> > claimcoins; try { claimcoins = scanner.GetUnspentTransactionOutputs(claimAddresses, userclaim.CoinShortName, out bool usedExplorer); } catch (Exception e) { return(RedirectToAction("ClaimError", new { message = "Error searching for your addresses in the blockchain", claimId = claimId })); } var amounts = scanner.CalculateOutputAmounts_Their_My_Fee(claimcoins.Item1, 0.05, 0.0003 * claimcoins.Item1.Count); var balances = claimcoins.Item2; // Return converted addresses to user List <InputAddress> inputs; inputs = GetInputAddresses(userclaim, list, balances); userclaim.InputAddresses = inputs; userclaim.Deposited = Convert.ToDouble(amounts[0].ToDecimal(MoneyUnit.BTC)); userclaim.MyFee = Convert.ToDouble(amounts[1].ToDecimal(MoneyUnit.BTC)); userclaim.MinerFee = Convert.ToDouble(amounts[2].ToDecimal(MoneyUnit.BTC)); userclaim.TotalValue = userclaim.Deposited + userclaim.MyFee + userclaim.MinerFee; userclaim.InitializeDate = DateTime.Now; if (userclaim.Deposited < 0) { userclaim.Deposited = 0; } if (userclaim.MyFee < 0) { userclaim.MyFee = 0; } // Generate unsigned tx var mydepaddr = ConfigurationManager.AppSettings[userclaim.CoinShortName + "Deposit"]; if (userclaim.CoinShortName == "BCH" && mydepaddr.StartsWith("bitcoincash:")) { // Convert mydepaddr = SharpCashAddr.Converter.cashAddrToOldAddr(mydepaddr, out bool isP2PKH, out _); } var utx = Bitcoin.GenerateUnsignedTX( UTXOs: claimcoins.Item1, amounts: amounts, clientDepAddr: Bitcoin.ParseAddress(depositAddress, userclaim.CoinShortName, BitcoinForks.ForkByShortName[userclaim.CoinShortName].Network), MyDepositAddr: Bitcoin.ParseAddress(mydepaddr, userclaim.CoinShortName, BitcoinForks.ForkByShortName[userclaim.CoinShortName].Network), forkShortName: userclaim.CoinShortName); userclaim.UnsignedTX = utx; // Generate witness data var w = Bitcoin.GetBlockData(claimcoins.Item1); userclaim.BlockData = w; // New format of message BlockData bd = new BlockData() { fork = userclaim.CoinShortName, coins = claimcoins.Item1, utx = utx, addresses = balances.Select(kvp => kvp.Key).ToList(), }; string bdstr = NBitcoin.JsonConverters.Serializer.ToString(bd); userclaim.ClaimData = bdstr; db.SaveChanges(); MonitoringService.SendMessage("New " + userclaim.CoinShortName + " claim", "new claim Initialized. https://www.coinpanic.com/Claim/ClaimConfirm?claimId=" + claimId + " " + " for " + userclaim.CoinShortName); } return(RedirectToAction("ClaimConfirm", new { claimId = claimId })); }
private static string TransmitViaJSONRPC(string ClaimId, CoinpanicContext db, CoinClaim userclaim, string signedTransaction, string coin) { GetConnectionDetails(coin, out string host, out int port, out string user, out string pass); var client = new RestClient("http://" + host + ":" + Convert.ToString(port)); client.Authenticator = new HttpBasicAuthenticator(user, pass); var request = new RestRequest("/", Method.POST); request.RequestFormat = DataFormat.Json; request.AddBody(new { jsonrpc = "1.0", id = "1", method = "sendrawtransaction", @params = new List <string>() { signedTransaction }, }); var restResponse = client.Execute(request); var content = restResponse.Content; // raw content as string userclaim.TransactionHash = content; userclaim.WasTransmitted = true; userclaim.SubmitDate = DateTime.Now; db.SaveChanges(); MonitoringService.SendMessage("New " + userclaim.CoinShortName + " broadcasting via explorer " + Convert.ToString(userclaim.TotalValue), "Claim broadcast: https://www.coinpanic.com/Claim/ClaimConfirm?claimId=" + ClaimId + " " + " for " + userclaim.CoinShortName + "\r\n " + signedTransaction); return(content); }
public ActionResult Broadcast(string ClaimId, string Hex) { /* * Known Errors: * * Missing a signature on one or more input (private key) * {"result":null,"error":{"code":-26,"message":"16: mandatory-script-verify-flag-failed (Operation not valid with the current stack size)"},"id":"1"} */ using (CoinpanicContext db = new CoinpanicContext()) { CoinClaim userclaim = db.Claims.Where(c => c.ClaimId == ClaimId).FirstOrDefault(); if (userclaim == null) { userclaim = new CoinClaim(); } //Clean up the signed transaction Hex string signedTransaction = Hex; signedTransaction = signedTransaction.Replace("\n", String.Empty); signedTransaction = signedTransaction.Replace("\r", String.Empty); signedTransaction = signedTransaction.Replace("\t", String.Empty); signedTransaction = signedTransaction.Trim().Replace(" ", ""); userclaim.SignedTX = signedTransaction; userclaim.SubmitDate = DateTime.Now; if (signedTransaction != "") { db.SaveChanges(); } // This is what is returned to the client BroadcastResponse response = new BroadcastResponse() { Error = false, Result = "Transaction successfully broadcast.", Txid = "", }; var tx = signedTransaction; if (tx == "") { response.Error = true; response.Result = "Error: No signed transaction provided."; MonitoringService.SendMessage("Empty tx " + userclaim.CoinShortName + " submitted.", "Claim broadcast: https://www.coinpanic.com/Claim/ClaimConfirm?claimId=" + ClaimId); return(Json(response)); } Transaction t = null; try { t = Transaction.Parse(tx.Trim().Replace(" ", "")); } catch (Exception e) { response.Error = true; response.Result = "Error parsing transaction"; MonitoringService.SendMessage("Invalid tx " + userclaim.CoinShortName + " submitted " + Convert.ToString(userclaim.TotalValue), "Claim broadcast: https://www.coinpanic.com/Claim/ClaimConfirm?claimId=" + ClaimId + " " + " for " + userclaim.CoinShortName + "\r\n " + signedTransaction + "\r\n" + e.Message); return(Json(response)); } // Transmit via explorers if (userclaim.CoinShortName == "BCA") { try { var url = "https://explorer.bitcoinatom.io/"; var client = new RestClient(url); var request = new RestRequest("/rpc-terminal/", Method.POST); request.AddHeader("content-type", "application/x-www-form-urlencoded"); request.AddHeader("x-requested-with", "XMLHttpRequest"); request.AddObject(new { cmd = "sendrawtransaction " + signedTransaction }); IRestResponse restResponse = client.Execute(request); var content = restResponse.Content; // raw content as string userclaim.TransactionHash = content; userclaim.WasTransmitted = true; userclaim.SubmitDate = DateTime.Now; db.SaveChanges(); MonitoringService.SendMessage("New " + userclaim.CoinShortName + " broadcasting via explorer " + Convert.ToString(userclaim.TotalValue), "Claim broadcast: https://www.coinpanic.com/Claim/ClaimConfirm?claimId=" + ClaimId + " " + " for " + userclaim.CoinShortName + "\r\n " + signedTransaction + "\r\n Result: " + content); response.Result = content; return(Json(response)); } catch (Exception e) { MonitoringService.SendMessage(userclaim.CoinShortName + " explorer send failed", e.Message); } } if (userclaim.CoinShortName == "B2X") { try { var client = new RestClient("https://explorer.b2x-segwit.io/b2x-insight-api/"); var request = new RestRequest("tx/send/", Method.POST); request.AddJsonBody(new { rawtx = signedTransaction }); IRestResponse restResponse = client.Execute(request); var content = restResponse.Content; // raw content as string userclaim.TransactionHash = content; userclaim.WasTransmitted = true; userclaim.SubmitDate = DateTime.Now; db.SaveChanges(); MonitoringService.SendMessage("New " + userclaim.CoinShortName + " broadcasting via explorer " + Convert.ToString(userclaim.TotalValue), "Claim broadcast: https://www.coinpanic.com/Claim/ClaimConfirm?claimId=" + ClaimId + " " + " for " + userclaim.CoinShortName + "\r\n " + signedTransaction + "\r\n Result: " + content); response.Result = content; return(Json(response)); } catch (Exception e) { MonitoringService.SendMessage(userclaim.CoinShortName + " explorer send failed", e.Message); } } if (userclaim.CoinShortName == "SBTC") { //http://block.superbtc.org/insight-api/tx/send try { var client = new RestClient("http://block.superbtc.org/insight-api/"); var request = new RestRequest("tx/send/", Method.POST); request.AddJsonBody(new { rawtx = signedTransaction }); IRestResponse restResponse = client.Execute(request); var content = restResponse.Content; // raw content as string userclaim.TransactionHash = content; userclaim.WasTransmitted = true; userclaim.SubmitDate = DateTime.Now; db.SaveChanges(); MonitoringService.SendMessage("New " + userclaim.CoinShortName + " broadcasting via explorer " + Convert.ToString(userclaim.TotalValue), "Claim broadcast: https://www.coinpanic.com/Claim/ClaimConfirm?claimId=" + ClaimId + " " + " for " + userclaim.CoinShortName + "\r\n " + signedTransaction + "\r\n Result: " + content); response.Result = content; return(Json(response)); } catch (Exception e) { MonitoringService.SendMessage(userclaim.CoinShortName + " explorer send failed", e.Message); } } if (userclaim.CoinShortName == "BCI") { //https://explorer.bitcoininterest.io/api/ try { var client = new RestClient("https://explorer.bitcoininterest.io/api/"); var request = new RestRequest("tx/send/", Method.POST); request.AddJsonBody(new { rawtx = signedTransaction }); IRestResponse restResponse = client.Execute(request); var content = restResponse.Content; // raw content as string userclaim.TransactionHash = content; userclaim.WasTransmitted = true; userclaim.SubmitDate = DateTime.Now; db.SaveChanges(); MonitoringService.SendMessage("New " + userclaim.CoinShortName + " broadcasting via explorer " + Convert.ToString(userclaim.TotalValue), "Claim broadcast: https://www.coinpanic.com/Claim/ClaimConfirm?claimId=" + ClaimId + " " + " for " + userclaim.CoinShortName + "\r\n " + signedTransaction + "\r\n Result: " + content); response.Result = content; return(Json(response)); } catch (Exception e) { MonitoringService.SendMessage(userclaim.CoinShortName + " explorer send failed", e.Message); } } if (userclaim.CoinShortName == "BCX") { //https://explorer.bitcoininterest.io/api/ try { var client = new RestClient("https://bcx.info/insight-api/"); var request = new RestRequest("tx/send/", Method.POST); request.AddJsonBody(new { rawtx = signedTransaction }); IRestResponse restResponse = client.Execute(request); var content = restResponse.Content; // raw content as string userclaim.TransactionHash = content; userclaim.WasTransmitted = true; userclaim.SubmitDate = DateTime.Now; db.SaveChanges(); MonitoringService.SendMessage("New " + userclaim.CoinShortName + " broadcasting via explorer " + Convert.ToString(userclaim.TotalValue), "Claim broadcast: https://www.coinpanic.com/Claim/ClaimConfirm?claimId=" + ClaimId + " " + " for " + userclaim.CoinShortName + "\r\n " + signedTransaction + "\r\n Result: " + content); response.Result = content; return(Json(response)); } catch (Exception e) { MonitoringService.SendMessage(userclaim.CoinShortName + " explorer send failed", e.Message); } } // Broadcast via own nodes over RPC if (userclaim.CoinShortName == "BBC" || userclaim.CoinShortName == "BTF" || userclaim.CoinShortName == "BCL" || userclaim.CoinShortName == "BCBC" || userclaim.CoinShortName == "BTV" || userclaim.CoinShortName == "BCD" || userclaim.CoinShortName == "UBTC" || userclaim.CoinShortName == "BTW" || userclaim.CoinShortName == "BPA") { try { string content = TransmitViaJSONRPC(ClaimId, db, userclaim, signedTransaction, userclaim.CoinShortName); response.Result = content; return(Json(response)); } catch (Exception e) { MonitoringService.SendMessage(userclaim.CoinShortName + " RPC send failed", e.Message); } } if (userclaim.CoinShortName == "BTCP") { try { var client = new RestClient("https://explorer.btcprivate.org/api/"); var request = new RestRequest("tx/send/", Method.POST); request.AddJsonBody(new { rawtx = signedTransaction }); //request.AddParameter("rawtx", signedTransaction); IRestResponse restResponse = client.Execute(request); var content = restResponse.Content; // raw content as string //ViewBag.content = content; userclaim.TransactionHash = content; userclaim.WasTransmitted = true; userclaim.SubmitDate = DateTime.Now; db.SaveChanges(); MonitoringService.SendMessage("New " + userclaim.CoinShortName + " broadcasting via explorer " + Convert.ToString(userclaim.TotalValue), "Claim broadcast: https://www.coinpanic.com/Claim/ClaimConfirm?claimId=" + ClaimId + " " + " for " + userclaim.CoinShortName + "\r\n " + signedTransaction); response.Result = content; return(Json(response)); } catch (Exception e) { MonitoringService.SendMessage(userclaim.CoinShortName + " explorer send failed", e.Message); } } else if (userclaim.CoinShortName == "BTG") { try { var client = new RestClient("https://explorer.bitcoingold.org/insight-api/"); var request = new RestRequest("tx/send/", Method.POST); request.AddJsonBody(new { rawtx = signedTransaction }); //request.AddParameter("rawtx", signedTransaction); IRestResponse restResponse = client.Execute(request); var content = restResponse.Content; // raw content as string //ViewBag.content = content; userclaim.TransactionHash = content; userclaim.WasTransmitted = true; userclaim.SubmitDate = DateTime.Now; db.SaveChanges(); MonitoringService.SendMessage("New " + userclaim.CoinShortName + " broadcasting via explorer " + Convert.ToString(userclaim.TotalValue), "Claim broadcast: https://www.coinpanic.com/Claim/ClaimConfirm?claimId=" + ClaimId + " " + " for " + userclaim.CoinShortName + "\r\n " + signedTransaction); response.Result = content; return(Json(response)); } catch (Exception e) { MonitoringService.SendMessage(userclaim.CoinShortName + " explorer send failed", e.Message); } } if (userclaim.CoinShortName == "BTX") { try { var client = new RestClient("https://insight.bitcore.cc/api/"); var request = new RestRequest("tx/send", Method.POST); //request.AddJsonBody(new { rawtx = signedTransaction }); request.AddParameter("rawtx", signedTransaction); request.RequestFormat = DataFormat.Json; //request.AddUrlSegment("rawtx", signedTransaction); IRestResponse restResponse = client.Execute(request); var content = restResponse.Content; // raw content as string //ViewBag.content = content; userclaim.TransactionHash = content; userclaim.WasTransmitted = true; userclaim.SubmitDate = DateTime.Now; db.SaveChanges(); MonitoringService.SendMessage("New " + userclaim.CoinShortName + " broadcasting via explorer " + Convert.ToString(userclaim.TotalValue), "Claim broadcast: https://www.coinpanic.com/Claim/ClaimConfirm?claimId=" + ClaimId + " " + " for " + userclaim.CoinShortName + "\r\n " + signedTransaction); response.Result = content; return(Json(response)); } catch (Exception e) { MonitoringService.SendMessage(userclaim.CoinShortName + " explorer send failed", e.Message); } } if (userclaim.CoinShortName == "BTV") { //https://block.bitvote.one/tx/send ps://block.bitvote.one/insight-api/ try { var client = new RestClient("https://block.bitvote.one/insight-api/"); var request = new RestRequest("tx/send/", Method.POST); request.AddJsonBody(new { rawtx = signedTransaction }); //request.AddParameter("rawtx", signedTransaction); IRestResponse restResponse = client.Execute(request); var content = restResponse.Content; // raw content as string //ViewBag.content = content; userclaim.TransactionHash = content; userclaim.WasTransmitted = true; userclaim.SubmitDate = DateTime.Now; db.SaveChanges(); MonitoringService.SendMessage("New " + userclaim.CoinShortName + " broadcasting via explorer " + Convert.ToString(userclaim.TotalValue), "Claim broadcast: https://www.coinpanic.com/Claim/ClaimConfirm?claimId=" + ClaimId + " " + " for " + userclaim.CoinShortName + "\r\n " + signedTransaction); response.Result = content; return(Json(response)); } catch (Exception e) { MonitoringService.SendMessage(userclaim.CoinShortName + " explorer send failed", e.Message); } } if (userclaim.CoinShortName == "BTP") { try { var client = new RestClient("http://exp.btceasypay.com/insight-api/"); var request = new RestRequest("tx/send/", Method.POST); request.AddJsonBody(new { rawtx = signedTransaction }); IRestResponse restResponse = client.Execute(request); var content = restResponse.Content; // raw content as string userclaim.TransactionHash = content; userclaim.WasTransmitted = true; userclaim.SubmitDate = DateTime.Now; db.SaveChanges(); MonitoringService.SendMessage("New " + userclaim.CoinShortName + " broadcasting via explorer " + Convert.ToString(userclaim.TotalValue), "Claim broadcast: https://www.coinpanic.com/Claim/ClaimConfirm?claimId=" + ClaimId + " " + " for " + userclaim.CoinShortName + "\r\n " + signedTransaction); response.Result = content; return(Json(response)); } catch (Exception e) { MonitoringService.SendMessage(userclaim.CoinShortName + " explorer send failed", e.Message); } } // Transmit via Full Node try { string url = "https://www.metabittrader.com/" + userclaim.CoinShortName + "/"; var client = new RestClient(url); var request = new RestRequest("api/tx/", Method.POST); request.AddJsonBody(new { Hex = Hex, ClaimId = ClaimId }); IRestResponse <BroadcastResponse> restResponse = client.Execute <BroadcastResponse>(request); var content = restResponse.Data; // Forward result return(Json(content)); } catch (Exception e) { MonitoringService.SendMessage(userclaim.CoinShortName + " explorer send failed", e.Message); } response.Result = "Unknown error broadcasting."; response.Error = true; return(Json(response)); } }
private static List <InputAddress> GetInputAddresses(CoinClaim userclaim, List <string> list, Dictionary <string, double> balances = null) { List <InputAddress> inputs; if (userclaim.CoinShortName == "BTCP") { inputs = list.Select(li => new InputAddress() { AddressId = Guid.NewGuid(), PublicAddress = li + " -> " + Bitcoin.ParseAddress(li).Convert(Network.BTCP).ToString(), CoinShortName = userclaim.CoinShortName, ClaimId = userclaim.ClaimId, ClaimValue = balances != null ? balances[li] : -1, }).ToList(); } else if (userclaim.CoinShortName == "BCI") { inputs = list.Select(li => new InputAddress() { AddressId = Guid.NewGuid(), PublicAddress = li + " -> " + Bitcoin.ParseAddress(li).Convert(Network.BCI).ToString(), CoinShortName = userclaim.CoinShortName, ClaimId = userclaim.ClaimId, ClaimValue = balances != null ? balances[li] : -1, }).ToList(); } else if (userclaim.CoinShortName == "BCA") { inputs = list.Select(li => new InputAddress() { AddressId = Guid.NewGuid(), PublicAddress = li + " -> " + Bitcoin.ParseAddress(li).Convert(Network.BCA).ToString(), CoinShortName = userclaim.CoinShortName, ClaimId = userclaim.ClaimId, ClaimValue = balances != null ? balances[li] : -1, }).ToList(); } else if (userclaim.CoinShortName == "BTG") { inputs = list.Select(li => new InputAddress() { AddressId = Guid.NewGuid(), PublicAddress = li + " -> " + Bitcoin.ParseAddress(li).Convert(Network.BTG).ToString(), CoinShortName = userclaim.CoinShortName, ClaimId = userclaim.ClaimId, ClaimValue = balances != null ? balances[li] : -1, }).ToList(); } else { inputs = list.Select(li => new InputAddress() { AddressId = Guid.NewGuid(), PublicAddress = li, CoinShortName = userclaim.CoinShortName, ClaimId = userclaim.ClaimId, ClaimValue = balances != null ? balances[li] : -1, }).ToList(); } return(inputs); }
public IHttpActionResult Post([FromBody] BroadcastModel b) { using (CoinpanicContext db = new CoinpanicContext()) { //MonitoringService.SendMessage("Received tx POST " + b.ClaimId, "Claim broadcast: https://www.coinpanic.com/Claim/ClaimConfirm?claimId=" + b.ClaimId ); CoinClaim userclaim = db.Claims.Where(c => c.ClaimId == b.ClaimId).FirstOrDefault(); if (userclaim == null) { userclaim = new CoinClaim(); } //Clean up the signed transaction Hex string signedTransaction = b.Hex; signedTransaction = signedTransaction.Replace("\n", String.Empty); signedTransaction = signedTransaction.Replace("\r", String.Empty); signedTransaction = signedTransaction.Replace("\t", String.Empty); signedTransaction = signedTransaction.Trim().Replace(" ", ""); userclaim.SignedTX = signedTransaction; userclaim.SubmitDate = DateTime.Now; db.SaveChanges(); BroadcastResponse response = new BroadcastResponse() { Error = false, Result = "Transaction successfully broadcast.", Txid = "", }; var tx = signedTransaction; if (tx == "") { response.Result = "Error: No signed transaction provided."; MonitoringService.SendMessage("Empty tx " + userclaim.CoinShortName + " submitted.", "Claim broadcast: https://www.coinpanic.com/Claim/ClaimConfirm?claimId=" + b.ClaimId); return(Ok(response)); } Transaction t = null; try { t = Transaction.Parse(tx.Trim().Replace(" ", "")); } catch (Exception e) { response.Error = true; response.Result = "Error parsing transaction"; MonitoringService.SendMessage("Invalid tx " + userclaim.CoinShortName + " submitted " + Convert.ToString(userclaim.TotalValue), "Claim broadcast: https://www.coinpanic.com/Claim/ClaimConfirm?claimId=" + b.ClaimId + " " + " for " + userclaim.CoinShortName + "\r\n " + signedTransaction); return(Ok(response)); } //BCX submit if (nodeService.Coin == "BCX") { } // Disable for now so that the full node is used (for segwit claims) if (false)//nodeService.Coin == "BTCP") { try { var client = new RestClient("https://explorer.btcprivate.org/api/"); var request = new RestRequest("tx/send/", Method.POST); request.AddJsonBody(new { rawtx = signedTransaction }); //request.AddParameter("rawtx", signedTransaction); IRestResponse restResponse = client.Execute(request); var content = restResponse.Content; // raw content as string //ViewBag.content = content; userclaim.TransactionHash = content; userclaim.WasTransmitted = true; userclaim.SubmitDate = DateTime.Now; db.SaveChanges(); MonitoringService.SendMessage("New " + userclaim.CoinShortName + " broadcasting via explorer " + Convert.ToString(userclaim.TotalValue), "Claim broadcast: https://www.coinpanic.com/Claim/ClaimConfirm?claimId=" + b.ClaimId + " " + " for " + userclaim.CoinShortName + "\r\n " + signedTransaction); response.Result = content; return(Ok(response)); } catch (Exception e) { MonitoringService.SendMessage("B2X explorer send failed", e.Message); } } if (nodeService.Coin == "BTG") { try { var client = new RestClient("https://explorer.bitcoingold.org/insight-api/"); var request = new RestRequest("tx/send/", Method.POST); request.AddJsonBody(new { rawtx = signedTransaction }); //request.AddParameter("rawtx", signedTransaction); IRestResponse restResponse = client.Execute(request); var content = restResponse.Content; // raw content as string //ViewBag.content = content; userclaim.TransactionHash = content; userclaim.WasTransmitted = true; userclaim.SubmitDate = DateTime.Now; db.SaveChanges(); MonitoringService.SendMessage("New " + userclaim.CoinShortName + " broadcasting via explorer " + Convert.ToString(userclaim.TotalValue), "Claim broadcast: https://www.coinpanic.com/Claim/ClaimConfirm?claimId=" + b.ClaimId + " " + " for " + userclaim.CoinShortName + "\r\n " + signedTransaction); response.Result = content; return(Ok(response)); } catch (Exception e) { MonitoringService.SendMessage(userclaim.CoinShortName + " explorer send failed", e.Message); } } if (nodeService.Coin == "BTX") { try { var client = new RestClient("http://insight.bitcore.cc/api/"); var request = new RestRequest("tx/send", Method.POST); request.AddJsonBody(new { rawtx = signedTransaction }); //request.AddParameter("rawtx", signedTransaction); IRestResponse restResponse = client.Execute(request); var content = restResponse.Content; // raw content as string //ViewBag.content = content; userclaim.TransactionHash = content; userclaim.WasTransmitted = true; userclaim.SubmitDate = DateTime.Now; db.SaveChanges(); MonitoringService.SendMessage("New " + userclaim.CoinShortName + " broadcasting via explorer " + Convert.ToString(userclaim.TotalValue), "Claim broadcast: https://www.coinpanic.com/Claim/ClaimConfirm?claimId=" + b.ClaimId + " " + " for " + userclaim.CoinShortName + "\r\n " + signedTransaction); response.Result = content; return(Ok(response)); } catch (Exception e) { MonitoringService.SendMessage(userclaim.CoinShortName + " explorer send failed", e.Message); } } if (nodeService.Coin == "B2X") { try { var client = new RestClient("https://explorer.b2x-segwit.io/b2x-insight-api/"); var request = new RestRequest("tx/send/", Method.POST); request.AddJsonBody(new { rawtx = signedTransaction }); //request.AddParameter("rawtx", signedTransaction); IRestResponse restResponse = client.Execute(request); var content = restResponse.Content; // raw content as string //ViewBag.content = content; userclaim.TransactionHash = content; userclaim.WasTransmitted = true; userclaim.SubmitDate = DateTime.Now; db.SaveChanges(); MonitoringService.SendMessage("New " + userclaim.CoinShortName + " broadcasting via explorer " + Convert.ToString(userclaim.TotalValue), "Claim broadcast: https://www.coinpanic.com/Claim/ClaimConfirm?claimId=" + b.ClaimId + " " + " for " + userclaim.CoinShortName + "\r\n " + signedTransaction); response.Result = content; return(Ok(response)); } catch (Exception e) { MonitoringService.SendMessage("B2X explorer send failed", e.Message); } } if (nodeService.Coin == "BTV") { //https://block.bitvote.one/tx/send ps://block.bitvote.one/insight-api/ try { var client = new RestClient("https://block.bitvote.one/insight-api/"); var request = new RestRequest("tx/send/", Method.POST); request.AddJsonBody(new { rawtx = signedTransaction }); //request.AddParameter("rawtx", signedTransaction); IRestResponse restResponse = client.Execute(request); var content = restResponse.Content; // raw content as string //ViewBag.content = content; userclaim.TransactionHash = content; userclaim.WasTransmitted = true; userclaim.SubmitDate = DateTime.Now; db.SaveChanges(); MonitoringService.SendMessage("New " + userclaim.CoinShortName + " broadcasting via explorer " + Convert.ToString(userclaim.TotalValue), "Claim broadcast: https://www.coinpanic.com/Claim/ClaimConfirm?claimId=" + b.ClaimId + " " + " for " + userclaim.CoinShortName + "\r\n " + signedTransaction); response.Result = content; return(Ok(response)); } catch (Exception e) { MonitoringService.SendMessage("BTV explorer send failed", e.Message); } } if (nodeService.Coin == "BTP") { try { var client = new RestClient("http://exp.btceasypay.com/insight-api/"); var request = new RestRequest("tx/send/", Method.POST); request.AddJsonBody(new { rawtx = signedTransaction }); //request.AddParameter("rawtx", signedTransaction); IRestResponse restResponse = client.Execute(request); var content = restResponse.Content; // raw content as string //ViewBag.content = content; userclaim.TransactionHash = content; userclaim.WasTransmitted = true; userclaim.SubmitDate = DateTime.Now; db.SaveChanges(); MonitoringService.SendMessage("New " + userclaim.CoinShortName + " broadcasting via explorer " + Convert.ToString(userclaim.TotalValue), "Claim broadcast: https://www.coinpanic.com/Claim/ClaimConfirm?claimId=" + b.ClaimId + " " + " for " + userclaim.CoinShortName + "\r\n " + signedTransaction); response.Result = content; return(Ok(response)); } catch (Exception e) { MonitoringService.SendMessage("BTV explorer send failed", e.Message); } //MonitoringService.SendMessage("New " + userclaim.CoinShortName + " begin broadcasting via explorer " + Convert.ToString(userclaim.TotalValue), "Claim broadcast: https://www.coinpanic.com/Claim/ClaimConfirm?claimId=" + b.ClaimId + " " + " for " + userclaim.CoinShortName + "\r\n " + signedTransaction); //var bitpieClient = new RestClient //{ // BaseUrl = new Uri("https://bitpie.getcai.com/api/v1/") //}; //var txRequest = new RestRequest("/btp/broadcast", Method.POST); //string data = "{\"raw_tx\": \""+ userclaim.SignedTX + "\"}"; //txRequest.AddParameter("application/json; charset=utf-8", data, ParameterType.RequestBody); //txRequest.RequestFormat = DataFormat.Json; //try //{ // var txresponse = bitpieClient.Execute(txRequest); // if (txresponse.IsSuccessful) // { // if (txresponse.Content == "{\"result\": 0, \"error\": \"\"}") // { // response.Result = "Transaction was broadcast. Network reported unknown error. Double check signatures and ensure coins not already claimed."; // } // else if (txresponse.Content == "{\"result\": 0, \"error\": \"broadcast error\"}") // { // response.Result = "Transaction successfully broadcast. No known errors identified."; // } // else // { // response.Result = "Transaction successfully broadcast. Result code: " + txresponse.Content; // } // response.Txid = t.GetHash().ToString(); // } // else // { // response.Result = "Error sending transactoin. Node service unavailable."; // } // Debug.Print(txresponse.StatusDescription); // MonitoringService.SendMessage("New " + userclaim.CoinShortName + " broadcast via explorer " + Convert.ToString(userclaim.TotalValue), "Claim broadcast: https://www.coinpanic.com/Claim/ClaimConfirm?claimId=" + b.ClaimId + " " + " for " + userclaim.CoinShortName + "\r\n " + signedTransaction); //} //catch (Exception e) //{ // MonitoringService.SendMessage("Tx server error", e.Message); // response.Result = "Transmission Error"; // return InternalServerError(); //} //return Ok(response); } //Regular nodes try { // If we don't have any connections, try to open them. if (nodeService.NumConnectedPeers < 1) { var seednodes = db.SeedNodes.Where(n => n.Coin == nodeService.Coin); nodeService.ConnectNodes(seednodes.Select(n => new NodeDetails() { coin = nodeService.Coin, ip = n.IP, port = n.Port, use = n.Enabled, }).ToList()); } string txid = t.GetHash().ToString(); response.Txid = txid; userclaim.TransactionHash = txid; db.SaveChanges(); var res = nodeService.BroadcastTransaction(t, false); if (res.IsError) { userclaim.WasTransmitted = false; userclaim.SignedTX = signedTransaction; MonitoringService.SendMessage("New " + userclaim.CoinShortName + " error broadcasting " + Convert.ToString(userclaim.TotalValue), "Claim broadcast: https://www.coinpanic.com/Claim/ClaimConfirm?claimId=" + b.ClaimId + " " + " for " + userclaim.CoinShortName + "\r\n txid: " + txid + "\r\nResult: " + res.Result); } else { userclaim.TransactionHash = txid; userclaim.WasTransmitted = true; userclaim.SignedTX = signedTransaction; MonitoringService.SendMessage("New " + userclaim.CoinShortName + " broadcasting " + Convert.ToString(userclaim.TotalValue), "Claim broadcast: https://www.coinpanic.com/Claim/ClaimConfirm?claimId=" + b.ClaimId + " " + " for " + userclaim.CoinShortName + "\r\n txid: " + txid + "\r\nResult: " + res.Result); } response.Result = res.Result; db.SaveChanges(); return(Ok(response)); } catch (Exception e) { MonitoringService.SendMessage("Tx server error", e.Message); return(InternalServerError()); } } }