public async Task <IBitcoinBasedTransaction> SignRefundTxAsync( IBitcoinBasedTransaction refundTx, IBitcoinBasedTransaction paymentTx, WalletAddress refundAddress) { var tx = refundTx.Clone(); if (tx.Inputs.Length != 1) { Log.Error("Refund transaction has zero or more than one input"); return(null); } var spentOutput = paymentTx.Outputs.FirstOrDefault(o => o.IsSwapPayment); if (spentOutput == null) { Log.Error("Payment transaction hasn't swap output"); return(null); } // firstly check, if transaction is already signed if (tx.Verify(spentOutput)) { return(tx); } // clean any signature, if exists tx.NonStandardSign(Script.Empty, 0); var sigHash = tx.GetSignatureHash(spentOutput); var signature = await Account.Wallet .SignHashAsync( hash : sigHash, address : refundAddress) .ConfigureAwait(false); if (signature == null) { Log.Error("Refund transaction signature error"); return(null); } var refundScript = BitcoinBasedSwapTemplate.GenerateHtlcSwapRefund( aliceRefundSig: signature, aliceRefundPubKey: refundAddress.PublicKeyBytes()); tx.NonStandardSign(refundScript, spentOutput); if (!tx.Verify(spentOutput, out var errors)) { Log.Error("Refund transaction verify errors: {errors}", errors); return(null); } return(tx); }
public async Task <IBitcoinBasedTransaction> SignHtlcSwapRedeemForP2ShTxAsync( IBitcoinBasedTransaction redeemTx, IBitcoinBasedTransaction paymentTx, WalletAddress redeemAddress, byte[] secret, byte[] redeemScript) { var tx = redeemTx.Clone(); var spentOutput = paymentTx.Outputs .Cast <BitcoinBasedTxOutput>() .FirstOrDefault(o => o.IsPayToScriptHash(redeemScript)); if (spentOutput == null) { Log.Error("Payment transaction hasn't pay to script hash output for redeem script"); return(null); } var sigHash = tx.GetSignatureHash(new Script(redeemScript), spentOutput); var signature = await Account.Wallet .SignHashAsync( hash : sigHash, address : redeemAddress, currency : Account.Currencies.GetByName(Account.Currency)) .ConfigureAwait(false); if (signature == null) { Log.Error("Redeem transaction signature error"); return(null); } var redeemScriptSig = BitcoinBasedSwapTemplate.GenerateP2PkhSwapRedeemForP2Sh( sig: signature, pubKey: redeemAddress.PublicKeyBytes(), secret: secret, redeemScript: redeemScript); tx.NonStandardSign(redeemScriptSig, spentOutput); if (!tx.Verify(spentOutput, out var errors, Account.Config)) { Log.Error("Redeem transaction verify errors: {errors}", errors); return(null); } return(tx); }
public async Task <IBitcoinBasedTransaction> SignRedeemTxAsync( IBitcoinBasedTransaction redeemTx, IBitcoinBasedTransaction paymentTx, WalletAddress redeemAddress, byte[] secret) { var tx = redeemTx.Clone(); var spentOutput = paymentTx.Outputs.FirstOrDefault(o => o.IsSwapPayment); if (spentOutput == null) { Log.Error("Payment transaction hasn't swap output"); return(null); } var sigHash = tx.GetSignatureHash(spentOutput); var signature = await Account.Wallet .SignHashAsync( hash : sigHash, address : redeemAddress) .ConfigureAwait(false); if (signature == null) { Log.Error("Redeem transaction signature error"); return(null); } var redeemScript = BitcoinBasedSwapTemplate.GenerateHtlcP2PkhSwapRedeem( sig: signature, pubKey: redeemAddress.PublicKeyBytes(), secret: secret); tx.NonStandardSign(redeemScript, spentOutput); if (!tx.Verify(spentOutput, out var errors)) { Log.Error("Redeem transaction verify errors: {errors}", errors); return(null); } return(tx); }
public async Task <IBitcoinBasedTransaction> SignHtlcSwapRefundForP2ShTxAsync( IBitcoinBasedTransaction refundTx, IBitcoinBasedTransaction paymentTx, WalletAddress refundAddress, byte[] redeemScript) { var tx = refundTx.Clone(); if (tx.Inputs.Length != 1) { Log.Error("Refund transaction has zero or more than one input"); return(null); } var spentOutput = paymentTx.Outputs .Cast <BitcoinBasedTxOutput>() .FirstOrDefault(o => o.IsPayToScriptHash(redeemScript)); if (spentOutput == null) { Log.Error("Payment transaction hasn't pay to script hash output for redeem script"); return(null); } // firstly check, if transaction is already signed if (tx.Verify(spentOutput, Account.Config)) { return(tx); } // clean any signature, if exists tx.NonStandardSign(Script.Empty, 0); var sigHash = tx.GetSignatureHash(new Script(redeemScript), spentOutput); var signature = await Account.Wallet .SignHashAsync( hash : sigHash, address : refundAddress, currency : Account.Currencies.GetByName(Account.Currency)) .ConfigureAwait(false); if (signature == null) { Log.Error("Refund transaction signature error"); return(null); } var refundScriptSig = BitcoinBasedSwapTemplate.GenerateHtlcSwapRefundForP2Sh( aliceRefundSig: signature, aliceRefundPubKey: refundAddress.PublicKeyBytes(), redeemScript: redeemScript); tx.NonStandardSign(refundScriptSig, spentOutput); if (!tx.Verify(spentOutput, out var errors, Account.Config)) { Log.Error("Refund transaction verify errors: {errors}", errors); return(null); } return(tx); }