public static async Task <Transaction> AddEnoughFeesToTransaction (Transaction tx) { Transaction txToBeSent = null; var settings = settingsProvider.GetSettings(); try { var fees = await feeManager.GetFeeCoinsToAddToTransaction(tx); txToBeSent = tx; foreach (var item in fees) { txToBeSent.AddInput(new TxIn(new OutPoint(new uint256(item.TransactionId), item.OutputNumber))); TransactionSignRequest feePrivateKeySignRequest = new TransactionSignRequest { PrivateKey = item.PrivateKey.ToString(), TransactionToSign = txToBeSent.ToHex() }; var feeSignedTransaction = await SignTransactionWorker(feePrivateKeySignRequest, SigHash.All | SigHash.AnyoneCanPay); txToBeSent = new Transaction(feeSignedTransaction); } return(txToBeSent); } catch (Exception exp) { throw exp; } }
public static async Task <string> SignTransactionWorker(TransactionSignRequest signRequest, SigHash sigHash = SigHash.All) { var settings = settingsProvider.GetSettings(); Transaction tx = new Transaction(signRequest.TransactionToSign); Transaction outputTx = new Transaction(signRequest.TransactionToSign); var secret = new BitcoinSecret(signRequest.PrivateKey); var secretSegWitScriptPubKey = secret.PubKey.WitHash.ScriptPubKey; var previousTransactions = await GetPreviousTransactions(tx); outputTx = SignWithSinglePrivateKey(previousTransactions, outputTx, secret, sigHash); for (int i = 0; i < tx.Inputs.Count; i++) { var input = tx.Inputs[i]; outputTx = SignMultisigWithSinglePrivateKey(input, i, previousTransactions, outputTx, secret, sigHash); /* * // This part seems to be covered at the first part of the function * if (PayToPubkeyHashTemplate.Instance.CheckScriptPubKey(output.ScriptPubKey)) * { * var address = PayToPubkeyHashTemplate.Instance.ExtractScriptPubKeyParameters(output.ScriptPubKey) * .GetAddress(settings.Network).ToWif(); * if (address == secret.GetAddress().ToWif()) * { * var hash = Script.SignatureHash(output.ScriptPubKey, tx, i, sigHash); * var signature = secret.PrivateKey.Sign(hash, sigHash); * * outputTx.Inputs[i].ScriptSig = PayToPubkeyHashTemplate.Instance.GenerateScriptSig(signature, secret.PubKey); * } * * continue; * } */ } return(outputTx.ToHex()); }
public static async Task <string> SignTransactionWorker(TransactionSignRequest signRequest, SigHash sigHash = SigHash.All) { BlockchainExplorerHelper daemonHelper = new BlockchainExplorerHelper(); var settings = Settings.ReadAppSettings(); Transaction tx = new Transaction(signRequest.TransactionToSign); Transaction outputTx = new Transaction(signRequest.TransactionToSign); var secret = new BitcoinSecret(signRequest.PrivateKey); TransactionBuilder builder = new TransactionBuilder(); builder.ContinueToBuild(tx); Transaction[] previousTransactions = new Transaction[tx.Inputs.Count]; for (int i = 0; i < previousTransactions.Count(); i++) { var txResponse = await daemonHelper.GetTransactionHex(settings, tx.Inputs[i].PrevOut.Hash.ToString()); if (txResponse.HasErrorOccurred) { throw new Exception(string.Format("Error while retrieving transaction {0}, error is: {1}", tx.Inputs[i].PrevOut.Hash.ToString(), txResponse.Error)); } previousTransactions[i] = new Transaction(txResponse.TransactionHex); builder.AddCoins(new Coin(previousTransactions[i], tx.Inputs[i].PrevOut.N)); } tx = builder.AddKeys(new BitcoinSecret[] { secret }).SignTransaction(tx, sigHash); for (int i = 0; i < tx.Inputs.Count; i++) { var input = tx.Inputs[i]; var prevTransaction = previousTransactions[i]; var output = prevTransaction.Outputs[input.PrevOut.N]; Coin c = new Coin(prevTransaction, input.PrevOut.N); builder.AddCoins(c); if (PayToScriptHashTemplate.Instance.CheckScriptPubKey(output.ScriptPubKey)) { var redeemScript = PayToScriptHashTemplate.Instance.ExtractScriptSigParameters(input.ScriptSig).RedeemScript; if (PayToMultiSigTemplate.Instance.CheckScriptPubKey(redeemScript)) { var pubkeys = PayToMultiSigTemplate.Instance.ExtractScriptPubKeyParameters(redeemScript).PubKeys; for (int j = 0; j < pubkeys.Length; j++) { if (secret.PubKey.ToHex() == pubkeys[j].ToHex()) { var scriptParams = PayToScriptHashTemplate.Instance.ExtractScriptSigParameters(input.ScriptSig); var hash = Script.SignatureHash(scriptParams.RedeemScript, tx, i, sigHash); var signature = secret.PrivateKey.Sign(hash, sigHash); scriptParams.Pushes[j + 1] = signature.Signature.ToDER().Concat(new byte[] { (byte)sigHash }).ToArray(); outputTx.Inputs[i].ScriptSig = PayToScriptHashTemplate.Instance.GenerateScriptSig(scriptParams); } } } continue; } if (PayToPubkeyHashTemplate.Instance.CheckScriptPubKey(output.ScriptPubKey)) { var address = PayToPubkeyHashTemplate.Instance.ExtractScriptPubKeyParameters(output.ScriptPubKey).GetAddress(settings.Network).ToWif(); if (address == secret.GetAddress().ToWif()) { var hash = Script.SignatureHash(output.ScriptPubKey, tx, i, sigHash); var signature = secret.PrivateKey.Sign(hash, sigHash); outputTx.Inputs[i].ScriptSig = PayToPubkeyHashTemplate.Instance.GenerateScriptSig(signature, secret.PubKey); } continue; } } return(outputTx.ToHex()); }