public TrustedBroadcastRequest CreateRedeemTransaction(FeeRate feeRate, Script redeemDestination) { if (feeRate == null) { throw new ArgumentNullException(nameof(feeRate)); } var coin = InternalState.EscrowedCoin; var escrow = EscrowScriptBuilder.ExtractEscrowScriptPubKeyParameters(coin.Redeem); Transaction tx = new Transaction(); tx.LockTime = escrow.LockTime; tx.Inputs.Add(new TxIn(coin.Outpoint)); tx.Inputs[0].Sequence = 0; tx.Outputs.Add(new TxOut(coin.Amount, redeemDestination)); tx.Inputs[0].ScriptSig = EscrowScriptBuilder.GenerateScriptSig(new TransactionSignature[] { null }) + Op.GetPushOp(coin.Redeem.ToBytes()); var vSize = tx.GetVirtualSize() + 80; // Size without signature + the signature size tx.Outputs[0].Value -= feeRate.GetFee(vSize); var redeemTransaction = new TrustedBroadcastRequest { Key = InternalState.RedeemKey, PreviousScriptPubKey = coin.Redeem.Hash.ScriptPubKey, Transaction = tx }; //Strip redeem script information so we check if TrustedBroadcastRequest can sign correctly redeemTransaction.Transaction = redeemTransaction.ReSign(new Coin(coin.Outpoint, coin.TxOut)); return(redeemTransaction); }
public override bool CanCombineScriptSig(Script scriptPubKey, Script a, Script b) { var escrow = EscrowScriptBuilder.ExtractEscrowScriptPubKeyParameters(scriptPubKey); if (escrow == null) { return(false); } var aSigs = EscrowScriptBuilder.ExtractScriptSigParameters(a); var bSigs = EscrowScriptBuilder.ExtractScriptSigParameters(b); if (aSigs == null || bSigs == null) { return(true); } return(aSigs.Length == bSigs.Length); }
public override Script CombineScriptSig(Script scriptPubKey, Script a, Script b) { // Combine all the signatures we've got: var aSigs = EscrowScriptBuilder.ExtractScriptSigParameters(a); if (aSigs == null) { return(b); } var bSigs = EscrowScriptBuilder.ExtractScriptSigParameters(b); if (bSigs == null) { return(a); } if (aSigs.Length == 1) { var sig = aSigs[0] ?? bSigs[0]; return(new Script(Op.GetPushOp(sig.ToBytes()))); } int sigCount = 0; TransactionSignature[] sigs = new TransactionSignature[2]; for (int i = 0; i < 2; i++) { var aSig = i < aSigs.Length ? aSigs[i] : null; var bSig = i < bSigs.Length ? bSigs[i] : null; var sig = aSig ?? bSig; if (sig != null) { sigs[i] = sig; sigCount++; } if (sigCount == 2) { break; } } if (sigCount == 2) { sigs = sigs.Where(s => s != null && s != TransactionSignature.Empty).ToArray(); } return(EscrowScriptBuilder.GenerateScriptSig(sigs)); }
public override Script GenerateScriptSig(Script scriptPubKey, IKeyRepository keyRepo, ISigner signer) { var multiSigParams = EscrowScriptBuilder.ExtractEscrowScriptPubKeyParameters(scriptPubKey); TransactionSignature[] signatures = new TransactionSignature[2]; var keys = multiSigParams .EscrowKeys .Select(p => keyRepo.FindKey(p.ScriptPubKey)) .ToArray(); if (keys.All(k => k == null)) { var redeem = keyRepo.FindKey(multiSigParams.RedeemKey.ScriptPubKey); if (redeem == null) { return(null); } return(new Script(Op.GetPushOp(signer.Sign(redeem).ToBytes()))); } int sigCount = 0; for (int i = 0; i < keys.Length; i++) { if (sigCount == 2) { break; } if (keys[i] != null) { var sig = signer.Sign(keys[i]); signatures[i] = sig; sigCount++; } } IEnumerable <TransactionSignature> sigs = signatures; if (sigCount == 2) { sigs = sigs.Where(s => s != TransactionSignature.Empty && s != null); } return(EscrowScriptBuilder.GenerateScriptSig(sigs.ToArray())); }
public virtual void ConfigureEscrowedCoin(ScriptCoin escrowedCoin, Key escrowKey, Key redeemKey) { if (escrowedCoin == null) { throw new ArgumentNullException(nameof(escrowedCoin)); } if (escrowKey == null) { throw new ArgumentNullException(nameof(escrowKey)); } if (redeemKey == null) { throw new ArgumentNullException(nameof(redeemKey)); } var escrow = EscrowScriptBuilder.ExtractEscrowScriptPubKeyParameters(escrowedCoin.Redeem); if (escrow == null || !escrow.EscrowKeys.Any(e => e == escrowKey.PubKey)) { throw new PuzzleException("Invalid escrow"); } InternalState.EscrowedCoin = escrowedCoin; InternalState.EscrowKey = escrowKey; InternalState.RedeemKey = redeemKey; }
public override int EstimateScriptSigSize(Script scriptPubKey) { return(EscrowScriptBuilder.GenerateScriptSig(Enumerable.Range(0, 2).Select(o => DummySignature).ToArray()).Length); }
public override bool CanGenerateScriptSig(Script scriptPubKey) { return(EscrowScriptBuilder.ExtractEscrowScriptPubKeyParameters(scriptPubKey) != null); }