public async Task <bool> Verify(string trHex, string pubKey, SigHash hashType = SigHash.All) { PubKey checkPubKey = new PubKey(pubKey); var tr = new Transaction(trHex); for (var i = 0; i < tr.Inputs.Count; i++) { var input = tr.Inputs[i]; var redeemScript = PayToScriptHashTemplate.Instance.ExtractScriptSigParameters(input.ScriptSig)?.RedeemScript ?? PayToScriptHashTemplate.Instance.ExtractScriptSigParameters(input.WitScript)?.RedeemScript; if (redeemScript != null) { if (PayToMultiSigTemplate.Instance.CheckScriptPubKey(redeemScript)) { var pubkeys = PayToMultiSigTemplate.Instance.ExtractScriptPubKeyParameters(redeemScript).PubKeys; for (int j = 0; j < pubkeys.Length; j++) { if (pubkeys[j] == checkPubKey) { var scriptParams = PayToScriptHashTemplate.Instance.ExtractScriptSigParameters(input.ScriptSig); var hash = Script.SignatureHash(scriptParams.RedeemScript, tr, i, hashType); if (!checkPubKey.Verify(hash, scriptParams.Pushes[j + 1])) { return(false); } } } continue; } } var prevTransaction = await _bitcoinTransactionService.GetTransaction(input.PrevOut.Hash.ToString()); var output = prevTransaction.Outputs[input.PrevOut.N]; if (PayToPubkeyHashTemplate.Instance.CheckScriptPubKey(output.ScriptPubKey)) { if (output.ScriptPubKey.GetDestinationAddress(_rpcParams.Network) == checkPubKey.GetAddress(_rpcParams.Network)) { var hash = Script.SignatureHash(output.ScriptPubKey, tr, i, hashType); var sign = PayToPubkeyHashTemplate.Instance.ExtractScriptSigParameters(input.ScriptSig)?.TransactionSignature?.Signature; if (sign == null) { return(false); } if (!checkPubKey.Verify(hash, sign)) { return(false); } } } } return(true); }
public async Task Cashout() { var currentMultiCashout = await _multiCashoutRepository.GetCurrentMultiCashout(); if (currentMultiCashout != null) { Transaction tx = null; try { tx = await _bitcoinTransactionService.GetTransaction(currentMultiCashout.TransactionHash); } catch { } if (tx != null) { await _multiCashoutRepository.CompleteMultiCashout(currentMultiCashout.MultipleCashoutId); } else { await RetryBroadcast(currentMultiCashout); } } var cashouts = (await _cashoutRequestRepository.GetOpenRequests()).OrderBy(o => o.Date).ToList(); if (!cashouts.Any()) { return; } var maxCount = await _settingsRepository.Get(Constants.MaxCountAggregatedCashouts, MaxCountAggregatedCashoutsDefault); var cashoutDelay = TimeSpan.FromSeconds(await _settingsRepository.Get(Constants.MaxCashoutDelaySeconds, MaxCashoutDelaySecondsDefault)); cashouts = cashouts.Take(maxCount).ToList(); if (cashouts.Count < maxCount && DateTime.UtcNow - cashouts.First().Date < cashoutDelay) { return; } var multiCashoutId = Guid.NewGuid(); CreateMultiCashoutTransactionResult createTxData = null; string signedHex; try { createTxData = await _lykkeTransactionBuilderService.GetMultipleCashoutTransaction(cashouts.ToList(), multiCashoutId); signedHex = await _signatureApi.SignTransaction(createTxData.Transaction.ToHex()); } catch (Exception) { if (createTxData != null) { await _spentOutputService.RemoveSpentOutputs(createTxData.Transaction); } throw; } var signedTx = new Transaction(signedHex); var txHash = signedTx.GetHash().ToString(); await _cashoutRequestRepository.SetMultiCashoutId(createTxData.UsedRequests.Select(o => o.CashoutRequestId), multiCashoutId); await _multiCashoutRepository.CreateMultiCashout(multiCashoutId, signedHex, txHash); await _bitcoinBroadcastService.BroadcastTransaction(multiCashoutId, createTxData.UsedRequests.Select(o => o.CashoutRequestId).ToList(), signedTx); await _multiCashoutRepository.CompleteMultiCashout(multiCashoutId); SendCompleteCashoutEvents(createTxData.UsedRequests, txHash); }
public async Task <IActionResult> AddCommitmentPunishmentPairOldDesign([FromQuery] string commitment, [FromQuery] string punishment) { if (string.IsNullOrEmpty(commitment) || string.IsNullOrEmpty(punishment)) { return(BadRequest("Passed parameters should not be null or empty")); } else { Transaction cTx = new Transaction(commitment); Transaction pTx = new Transaction(punishment); try { using (OffchainMonitorContext context = new OffchainMonitorContext()) { var newlyAddedCommitment = new CommitmentEntity { Commitment = commitment, Punishment = punishment }; bool found = false; var multisig = await settingsRepository.Get <string>("multisig"); var netwok = await Helper.GetNetwork(settingsRepository); for (int i = 0; i < cTx.Inputs.Count; i++) { var prevHash = cTx.Inputs[i].PrevOut.Hash.ToString(); var prevTx = await bitcoinTransactionService.GetTransaction(prevHash); var prevOut = cTx.Inputs[i].PrevOut; if (prevTx.Outputs[prevOut.N].ScriptPubKey.GetDestinationAddress(netwok).ToString() == multisig) { found = true; var existingMultisigOutput = (from o in context.MultisigOutputs where o.TransactionId == prevOut.Hash.ToString() && o.OutputNumber == prevOut.N select o).FirstOrDefault(); if (existingMultisigOutput == null) { var newMultisigOutput = new MultisigOutputEntity(); newMultisigOutput.TransactionId = prevOut.Hash.ToString(); newMultisigOutput.OutputNumber = (int)prevOut.N; newMultisigOutput.LastSeen = DateTime.UtcNow; await context.MultisigOutputs.AddAsync(newMultisigOutput); existingMultisigOutput = newMultisigOutput; } existingMultisigOutput.LastSeen = DateTime.UtcNow; existingMultisigOutput.Commitments.Add(newlyAddedCommitment); newlyAddedCommitment.CommitmentOutput = existingMultisigOutput; await context.Commitments.AddAsync(newlyAddedCommitment); } } if (!found) { return(BadRequest(string.Format("The provide transaction does not pay to multisig:{0}", multisig))); } await context.SaveChangesAsync(); } return(Ok()); } catch (Exception exp) { throw exp; } } }