예제 #1
0
        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);
        }
예제 #2
0
        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);
        }
예제 #3
0
        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));
        }
예제 #4
0
        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()));
        }
예제 #5
0
        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;
        }
예제 #6
0
 public override int EstimateScriptSigSize(Script scriptPubKey)
 {
     return(EscrowScriptBuilder.GenerateScriptSig(Enumerable.Range(0, 2).Select(o => DummySignature).ToArray()).Length);
 }
예제 #7
0
 public override bool CanGenerateScriptSig(Script scriptPubKey)
 {
     return(EscrowScriptBuilder.ExtractEscrowScriptPubKeyParameters(scriptPubKey) != null);
 }