protected override bool CheckScriptSigCore(Network network, Script scriptSig, Op[] scriptSigOps, Script scriptPubKey, Op[] scriptPubKeyOps)
 {
     if (!scriptSig.IsPushOnly)
     {
         return(false);
     }
     if (scriptSigOps[0].Code != OpcodeType.OP_0)
     {
         return(false);
     }
     if (scriptSigOps.Length == 1)
     {
         return(false);
     }
     if (!scriptSigOps.Skip(1).All(s => TransactionSignature.ValidLength(s.PushData.Length) || s.Code == OpcodeType.OP_0))
     {
         return(false);
     }
     if (scriptPubKeyOps != null)
     {
         if (!CheckScriptPubKeyCore(scriptPubKey, scriptPubKeyOps))
         {
             return(false);
         }
         int?sigCountExpected = scriptPubKeyOps[0].GetInt();
         if (sigCountExpected == null)
         {
             return(false);
         }
         return(sigCountExpected == scriptSigOps.Length + 1);
     }
     return(true);
 }
		public override Script GenerateScriptSig(Script scriptPubKey, IKeyRepository keyRepo, ISigner signer)
		{
			var multiSigParams = PayToMultiSigTemplate.Instance.ExtractScriptPubKeyParameters(scriptPubKey);
			TransactionSignature[] signatures = new TransactionSignature[multiSigParams.PubKeys.Length];
			var keys =
				multiSigParams
				.PubKeys
				.Select(p => keyRepo.FindKey(p.ScriptPubKey))
				.ToArray();

			int sigCount = 0;
			for(int i = 0 ; i < keys.Length ; i++)
			{
				if(sigCount == multiSigParams.SignatureCount)
					break;
				if(keys[i] != null)
				{
					var sig = signer.Sign(keys[i]);
					signatures[i] = sig;
					sigCount++;
				}
			}

			IEnumerable<TransactionSignature> sigs = signatures;
			if(sigCount == multiSigParams.SignatureCount)
			{
				sigs = sigs.Where(s => s != TransactionSignature.Empty && s != null);
			}
			return PayToMultiSigTemplate.Instance.GenerateScriptSig(sigs);
		}
Esempio n. 3
0
        public static TransactionSignature[] ExtractScriptSigParameters(Script scriptSig)
        {
            var ops = scriptSig.ToOps().ToArray();

            if (ops.Length == 3)
            {
                return(PayToMultiSigTemplate.Instance.ExtractScriptSigParameters(scriptSig));
            }
            else if (ops.Length == 1)
            {
                var sig = new TransactionSignature[1];
                try
                {
                    if (ops[0].Code != OpcodeType.OP_0)
                    {
                        sig[0] = new TransactionSignature(ops[0].PushData);
                    }
                }
                catch { return(null); }
                return(sig);
            }
            else
            {
                return(null);
            }
        }
Esempio n. 4
0
        private TransactionSignature MakeHighS(TransactionSignature sig)
        {
            var curveOrder = new NBitcoin.BouncyCastle.Math.BigInteger("115792089237316195423570985008687907852837564279074904382605163141518161494337", 10);
            var ecdsa      = new ECDSASignature(sig.Signature.R, sig.Signature.S.Negate().Mod(curveOrder));

            return(new TransactionSignature(ecdsa, sig.SigHash));
        }
Esempio n. 5
0
        public override void MergePartialSignatures(InputSigningContext inputSigningContext)
        {
            if (inputSigningContext.OriginalTxIn is null || inputSigningContext.TransactionContext.Transaction is null)
            {
                return;
            }
            var scriptSig      = inputSigningContext.OriginalTxIn.ScriptSig;
            var witScript      = inputSigningContext.OriginalTxIn.WitScript;
            var multiSigParams = PayToMultiSigTemplate.Instance.ExtractScriptPubKeyParameters(inputSigningContext.Coin.GetScriptCode());
            var txIn           = inputSigningContext.Input;
            var scriptPubKey   = inputSigningContext.Coin.GetScriptCode();

            var sigs     = new TransactionSignature[multiSigParams.PubKeys.Length];
            int sigCount = 0;

            for (int i = 0; i < multiSigParams.PubKeys.Length; i++)
            {
                if (txIn.PartialSigs.TryGetValue(multiSigParams.PubKeys[i], out sigs[i]))
                {
                    sigCount++;
                }
            }
            if (sigCount >= multiSigParams.SignatureCount)
            {
                return;                 // We have all signatures already, no need merging here, finalize will take care of it.
            }
            List <Op> ops = new List <Op>();

            ops.Add(OpcodeType.OP_0);
            for (int i = 0; i < multiSigParams.PubKeys.Length; i++)
            {
                if (sigs[i] is TransactionSignature sig)
                {
                    ops.Add(Op.GetPushOp(sig.ToBytes()));
                }
                else
                {
                    ops.Add(OpcodeType.OP_0);
                }
            }

            if (txIn.WitnessScript is Script s)
            {
                ops.Add(Op.GetPushOp(s.ToBytes()));
                inputSigningContext.OriginalTxIn.WitScript = new WitScript(ops.ToArray());
                if (txIn.RedeemScript is Script p2sh)
                {
                    inputSigningContext.OriginalTxIn.ScriptSig = new Script(Op.GetPushOp(p2sh.ToBytes()));
                }
            }
            else if (txIn.RedeemScript is Script s2)
            {
                ops.Add(Op.GetPushOp(s2.ToBytes()));
                inputSigningContext.OriginalTxIn.ScriptSig = new Script(ops.ToArray());
            }
            else
            {
                inputSigningContext.OriginalTxIn.ScriptSig = new Script(ops.ToArray());
            }
        }
Esempio n. 6
0
        private Transaction BuildSignedCloseTransaction(LocalChannel channel, TransactionSignature remoteClosingSignature, ulong feeSatoshi)
        {
            var builder = new CloseChannelTransactionBuilder(channel, _networkParameters);

            builder.FeeSatoshi = feeSatoshi;
            return(builder.BuildWithSignatures(remoteClosingSignature));
        }
        public override Script GenerateScriptSig(Network network, Script scriptPubKey, IKeyRepository keyRepo,
                                                 ISigner signer)
        {
            var multiSigParams = PayToMultiSigTemplate.Instance.ExtractScriptPubKeyParameters(scriptPubKey);
            var signatures     = new TransactionSignature[multiSigParams.PubKeys.Length];
            var keys           =
                multiSigParams
                .PubKeys
                .Select(p => keyRepo.FindKey(p.ScriptPubKey))
                .ToArray();

            var sigCount = 0;

            for (var i = 0; i < keys.Length; i++)
            {
                if (sigCount == multiSigParams.SignatureCount)
                {
                    break;
                }
                if (keys[i] != null)
                {
                    var sig = signer.Sign(keys[i]);
                    signatures[i] = sig;
                    sigCount++;
                }
            }

            IEnumerable <TransactionSignature> sigs = signatures;

            if (sigCount == multiSigParams.SignatureCount)
            {
                sigs = sigs.Where(s => s != TransactionSignature.Empty && s != null);
            }
            return(PayToMultiSigTemplate.Instance.GenerateScriptSig(sigs));
        }
		public override Script CombineScriptSig(Script scriptPubKey, Script a, Script b)
		{
			var para = PayToMultiSigTemplate.Instance.ExtractScriptPubKeyParameters(scriptPubKey);
			// Combine all the signatures we've got:
			var aSigs = PayToMultiSigTemplate.Instance.ExtractScriptSigParameters(a);
			if(aSigs == null)
				return b;
			var bSigs = PayToMultiSigTemplate.Instance.ExtractScriptSigParameters(b);
			if(bSigs == null)
				return a;
			int pubkeyCount = 0;
			TransactionSignature[] sigs = new TransactionSignature[para.PubKeys.Length];
			for(int i = 0 ; i < para.PubKeys.Length ; 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[pubkeyCount] = sig; 
					pubkeyCount++;
				}
				if(pubkeyCount == para.SignatureCount)
					break;
			}
			if(pubkeyCount == para.SignatureCount)
				sigs = sigs.Where(s => s != null && s != TransactionSignature.Empty).ToArray();
			return PayToMultiSigTemplate.Instance.GenerateScriptSig(sigs);
		}		
Esempio n. 9
0
        public IActionResult GiveEscapeKey(
            [ModelBinder(BinderType = typeof(TumblerParametersModelBinder))]
            ClassicTumblerParameters tumblerId,
            int cycleId, string channelId, [FromBody] TransactionSignature clientSignature)
        {
            if (tumblerId == null)
            {
                throw new ArgumentNullException("tumblerId");
            }
            var session = GetSolverServerSession(cycleId, channelId, CyclePhase.TumblerCashoutPhase);

            if (session.Status != SolverServerStates.WaitingEscape)
            {
                return(BadRequest("invalid-state"));
            }

            var fee = Services.FeeService.GetFeeRate();

            try
            {
                var cashout = Services.WalletService.GenerateAddress();
                var tx      = session.GetSignedEscapeTransaction(clientSignature, fee, cashout.ScriptPubKey);

                var correlation = GetCorrelation(session);
                Tracker.AddressCreated(cycleId, TransactionType.ClientEscape, cashout.ScriptPubKey, correlation);
                Tracker.TransactionCreated(cycleId, TransactionType.ClientEscape, tx.GetHash(), correlation);

                Services.BroadcastService.Broadcast(tx);
            }
            catch (PuzzleException ex)
            {
                return(BadRequest(ex.Message));
            }
            return(Ok());
        }
Esempio n. 10
0
        public Transaction GetSignedEscapeTransaction(TransactionSignature clientSignature, Script cashout)
        {
            AssertState(SolverServerStates.WaitingEscape);

            var escapeTx = GetUnsignedOfferTransaction();

            escapeTx.Outputs[0].ScriptPubKey = cashout;
            var clientKey = AssertValidSignature(clientSignature, escapeTx);

            TransactionBuilder builder = new TransactionBuilder();

            builder.StandardTransactionPolicy.CheckFee = false;
            builder.Extensions.Add(new EscrowBuilderExtension());
            builder.AddCoins(InternalState.EscrowedCoin);
            builder.AddKnownSignature(clientKey, clientSignature);
            //This add the known signature if correct SigHash
            builder.SignTransactionInPlace(escapeTx, SigHash.None | SigHash.AnyoneCanPay);

            //This sign SigHash.All
            builder.AddKeys(InternalState.EscrowKey);
            builder.SignTransactionInPlace(escapeTx);
            if (!builder.Verify(escapeTx))
            {
                throw new PuzzleException("invalid-tumbler-signature");
            }

            return(escapeTx);
        }
Esempio n. 11
0
 /// <summary>
 /// Creates a scriptSig that can redeem a pay-to-pubkey output.
 /// If given signature is null, incomplete scriptSig will be created with OP_0 instead of signature
 /// </summary>
 public static Script CreateInputScript(TransactionSignature signature)
 {
     byte[] sigBytes = signature != null?signature.EncodeToBitcoin() : new byte[]
     {
     };
     return(new ScriptBuilder().Data(sigBytes).Build());
 }
Esempio n. 12
0
        public override void Sign(InputSigningContext inputSigningContext, IKeyRepository keyRepository, ISigner signer)
        {
            var scriptCode     = inputSigningContext.Coin.GetScriptCode();
            var multiSigParams = PayToMultiSigTemplate.Instance.ExtractScriptPubKeyParameters(scriptCode);

            TransactionSignature?[] signatures = new TransactionSignature[multiSigParams.PubKeys.Length];
            var keys     = multiSigParams.PubKeys;
            int sigcount = 0;

            for (int i = 0; i < keys.Length && sigcount < multiSigParams.SignatureCount; i++)
            {
                var sig = signer.Sign(keys[i]) as TransactionSignature;
                signatures[i] = sig;
                if (sig != null)
                {
                    sigcount++;
                }
            }
            for (int i = 0; i < keys.Length; i++)
            {
                var sig = signatures[i];
                var key = keys[i];
                if (key is PubKey && sig is TransactionSignature s && s != TransactionSignature.Empty)
                {
                    inputSigningContext.Input.PartialSigs.TryAdd(key, sig);
                }
            }
        }
Esempio n. 13
0
        public TrustedBroadcastRequest FulfillOffer(
            TransactionSignature clientSignature,
            Script cashout,
            FeeRate feeRate)
        {
            if (clientSignature == null)
            {
                throw new ArgumentNullException(nameof(clientSignature));
            }
            if (feeRate == null)
            {
                throw new ArgumentNullException(nameof(feeRate));
            }
            AssertState(SolverServerStates.WaitingFulfillment);
            Script offerScript = GetOfferScript();

            var offer = GetUnsignedOfferTransaction();

            PubKey clientKey = AssertValidSignature(clientSignature, offer);

            TransactionBuilder builder = new TransactionBuilder();

            builder.StandardTransactionPolicy.CheckFee = false;
            builder.Extensions.Add(new EscrowBuilderExtension());
            builder.AddCoins(InternalState.EscrowedCoin);
            builder.AddKeys(InternalState.EscrowKey);
            builder.AddKnownSignature(clientKey, clientSignature);
            builder.SignTransactionInPlace(offer);
            if (!builder.Verify(offer))
            {
                throw new PuzzleException("invalid-tumbler-signature");
            }
            var offerCoin = offer.Outputs.AsCoins().First().ToScriptCoin(offerScript);

            var         solutions = InternalState.SolvedPuzzles.Select(s => s.SolutionKey).ToArray();
            Transaction fulfill   = new Transaction();

            fulfill.Inputs.Add(new TxIn(offerCoin.Outpoint));
            fulfill.Outputs.Add(new TxOut(offerCoin.Amount, cashout));

            var fulfillScript = SolverScriptBuilder.CreateFulfillScript(NBitcoin.BuilderExtensions.BuilderExtension.DummySignature, solutions);

            fulfill.Inputs[0].ScriptSig = fulfillScript + Op.GetPushOp(offerCoin.Redeem.ToBytes());

            fulfill.Outputs[0].Value -= feeRate.GetFee(fulfill.GetVirtualSize());

            var signature = fulfill.Inputs.AsIndexedInputs().First().Sign(InternalState.FulfillKey, offerCoin, SigHash.All);

            fulfillScript = SolverScriptBuilder.CreateFulfillScript(signature, solutions);
            fulfill.Inputs[0].ScriptSig = fulfillScript + Op.GetPushOp(offerCoin.Redeem.ToBytes());

            InternalState.OfferClientSignature = clientSignature;
            InternalState.Status = SolverServerStates.WaitingEscape;
            return(new TrustedBroadcastRequest
            {
                Key = InternalState.FulfillKey,
                PreviousScriptPubKey = offerCoin.ScriptPubKey,
                Transaction = fulfill
            });
        }
Esempio n. 14
0
 public static bool TryParse(string str, out PartialSignature?sig)
 {
     if (str == null)
     {
         throw new ArgumentNullException(nameof(str));
     }
     sig = null;
     try
     {
         var bytes = Encoders.Hex.DecodeData(str);
         if (bytes.Length < 2 + 33 + 1 || bytes[0] != 0x22 || bytes[1] != 0x02)
         {
             return(false);
         }
         var pk     = new NBitcoin.PubKey(bytes.AsSpan().Slice(2, 33).ToArray());
         var siglen = bytes[2 + 33];
         if (siglen < 75 && bytes.Length != 2 + 33 + 1 + siglen)
         {
             return(false);
         }
         var sigBytes = bytes.AsSpan().Slice(2 + 33 + 1).ToArray();
         if (!TransactionSignature.IsValid(sigBytes))
         {
             return(false);
         }
         var s = new TransactionSignature(sigBytes);
         sig = new PartialSignature(pk, s);
         return(true);
     }
     catch
     {
         return(false);
     }
 }
Esempio n. 15
0
        public IActionResult FulfillOffer(int cycleId, string channelId, [FromBody] TransactionSignature clientSignature)
        {
            var session = GetSolverServerSession(cycleId, channelId, CyclePhase.TumblerCashoutPhase);
            var feeRate = Services.FeeService.GetFeeRate();

            if (session.Status != SolverServerStates.WaitingFulfillment)
            {
                return(BadRequest("invalid-state"));
            }
            try
            {
                var cycle   = Parameters.CycleGenerator.GetCycle(cycleId);
                var cashout = Services.WalletService.GenerateAddress($"Cycle {cycle.Start} Tumbler Cashout");
                var fulfill = session.FulfillOffer(clientSignature, cashout.ScriptPubKey, feeRate);
                fulfill.BroadcastAt = new LockTime(cycle.GetPeriods().Payment.End - 1);
                Repository.Save(cycle.Start, session);

                var signedOffer = session.GetSignedOfferTransaction();
                signedOffer.BroadcastAt = fulfill.BroadcastAt - 1;
                Services.TrustedBroadcastService.Broadcast($"Cycle {cycle.Start} Client Offer Transaction (planned for: {signedOffer.BroadcastAt})", signedOffer);
                Services.TrustedBroadcastService.Broadcast($"Cycle {cycle.Start} Tumbler Fulfillment Transaction (planned for: {fulfill.BroadcastAt})", fulfill);
                return(Json(session.GetSolutionKeys()));
            }
            catch (PuzzleException)
            {
                return(BadRequest("invalid-offer"));
            }
        }
        protected override bool CheckScriptSigCore(Network network, Script scriptSig, Op[] scriptSigOps, Script scriptPubKey, Op[] scriptPubKeyOps)
        {
            if (!scriptSig.IsPushOnly)
            {
                return(false);
            }
            if (scriptSigOps[0].Code != OpcodeType.OP_0)
            {
                return(false);
            }
            if (scriptSigOps.Length == 1)
            {
                return(false);
            }
            if (!scriptSigOps.Skip(1).All(s => TransactionSignature.ValidLength(s.PushData.Length) || s.Code == OpcodeType.OP_0))
            {
                return(false);
            }

            if (scriptPubKeyOps != null)
            {
                if (!CheckScriptPubKeyCore(scriptPubKey, scriptPubKeyOps))
                {
                    return(false);
                }

                (PubKey[] pubKeys, int sigCountExpected) = ((StraxBaseNetwork)network).Federations.GetFederation(scriptPubKeyOps[0].PushData).GetFederationDetails();
                return(sigCountExpected == scriptSigOps.Length + 1);
            }

            return(true);
        }
Esempio n. 17
0
 /// <summary>
 /// Generates the scriptSig.
 /// </summary>
 /// <param name="signature">The transaction signature. For unsigned inputs this can be <c>null</c> in which case it is encoded as an <c>OP_0</c>.</param>
 /// <param name="coldPubKey">A flag indicating whether the cold wallet versus the hot wallet is signing.</param>
 /// <param name="publicKey">The cold or hot wallet public key.</param>
 /// <returns>The scriptSig.</returns>
 public Script GenerateScriptSig(TransactionSignature signature, bool coldPubKey, PubKey publicKey)
 {
     return(new Script(
                Op.GetPushOp(signature.ToBytes()),
                coldPubKey ? OpcodeType.OP_0 : OpcodeType.OP_1,
                Op.GetPushOp(publicKey.ToBytes())
                ));
 }
 protected override bool CheckScriptSigCore(Network network, Script scriptSig, Op[] scriptSigOps, Script scriptPubKey, Op[] scriptPubKeyOps)
 {
     Op[] ops = scriptSigOps;
     if (ops.Length != 1)
     {
         return(false);
     }
     return(ops[0].PushData != null && TransactionSignature.IsValid(network, ops[0].PushData));
 }
Esempio n. 19
0
 public async Task <Transaction> ReceiveAsync(ScriptCoin escrowedCoin, TransactionSignature clientSignature, Key escrowKey, FeeRate feeRate)
 {
     _ReceiveBatch.FeeRate = feeRate;
     return(await _ReceiveBatch.WaitTransactionAsync(new ClientEscapeData()
     {
         ClientSignature = clientSignature,
         EscrowedCoin = escrowedCoin,
         EscrowKey = escrowKey
     }).ConfigureAwait(false));
 }
Esempio n. 20
0
        public string Signature()
        {
            PayToMultiSigTemplateParameters multisigParams = PayToMultiSigTemplate.Instance.ExtractScriptPubKeyParameters(this.RedeemScript);

            int index = multisigParams.PubKeys.IndexOf(this.PubKey);

            TransactionSignature signature = PayToMultiSigTemplate.Instance.ExtractScriptSigParameters(this.Network, new Script(tx.Inputs[0].ScriptSig.ToOps().SkipLast(1)))[index];

            return(signature.ToString());
        }
Esempio n. 21
0
        public void ReadWrite(BitcoinStream stream)
        {
            var bytes = _Signature?.ToBytes();

            stream.ReadWriteAsVarString(ref bytes);
            if (!stream.Serializing)
            {
                _Signature = new TransactionSignature(bytes);
            }
        }
 public WitScript GenerateWitScript(TransactionSignature signature, PubKey publicKey)
 {
     if (publicKey == null)
     {
         throw new ArgumentNullException("publicKey");
     }
     return(new WitScript(
                signature == null ? OpcodeType.OP_0 : Op.GetPushOp(signature.ToBytes()),
                Op.GetPushOp(publicKey.ToBytes())
                ));
 }
Esempio n. 23
0
        private PubKey AssertValidSignature(TransactionSignature clientSignature, Transaction offer)
        {
            var signedHash = offer.Inputs.AsIndexedInputs().First().GetSignatureHash(InternalState.EscrowedCoin, clientSignature.SigHash);
            var clientKey  = InternalState.GetClientEscrowPubKey();

            if (!clientKey.Verify(signedHash, clientSignature.Signature))
            {
                throw new PuzzleException("invalid-client-signature");
            }
            return(clientKey);
        }
 protected override bool CheckScriptSigCore(Network network, Script scriptSig, Op[] scriptSigOps, Script scriptPubKey, Op[] scriptPubKeyOps)
 {
     Op[] ops = scriptSigOps;
     if (ops.Length != 2)
     {
         return(false);
     }
     return(ops[0].PushData != null &&
            ((ops[0].Code == OpcodeType.OP_0) || TransactionSignature.IsValid(network, ops[0].PushData, ScriptVerify.None)) &&
            ops[1].PushData != null && PubKey.Check(ops[1].PushData, false));
 }
Esempio n. 25
0
        public TrustedBroadcastRequest FulfillOffer(
            TransactionSignature clientSignature,
            Script cashout,
            FeeRate feeRate)
        {
            if (clientSignature == null)
            {
                throw new ArgumentNullException(nameof(clientSignature));
            }
            if (feeRate == null)
            {
                throw new ArgumentNullException(nameof(feeRate));
            }
            AssertState(SolverServerStates.WaitingFulfillment);

            var    offer     = GetUnsignedOfferTransaction();
            PubKey clientKey = AssertValidSignature(clientSignature, offer);

            offer.Inputs[0].ScriptSig = new Script(
                Op.GetPushOp(clientSignature.ToBytes()),
                Op.GetPushOp(CreateOfferSignature().ToBytes()),
                Op.GetPushOp(InternalState.EscrowedCoin.Redeem.ToBytes())
                );
            offer.Inputs[0].Witnessify();

            if (!offer.Inputs.AsIndexedInputs().First().VerifyScript(_Network, InternalState.EscrowedCoin))
            {
                throw new PuzzleException("invalid-tumbler-signature");
            }


            var         solutions = InternalState.SolvedPuzzles.Select(s => s.SolutionKey).ToArray();
            Transaction fulfill   = new Transaction();

            fulfill.Inputs.Add(new TxIn());
            fulfill.Outputs.Add(new TxOut(InternalState.OfferCoin.Amount, cashout));

            var fulfillScript = SolverScriptBuilder.CreateFulfillScript(null, solutions);

            fulfill.Inputs[0].ScriptSig = fulfillScript + Op.GetPushOp(InternalState.OfferCoin.Redeem.ToBytes());
            fulfill.Inputs[0].Witnessify();
            var virtualSize = fulfill.HasWitness ? fulfill.GetVirtualSize(_Network.Consensus.Options.WitnessScaleFactor) : fulfill.GetSerializedSize();

            fulfill.Outputs[0].Value -= feeRate.GetFee(virtualSize);

            InternalState.OfferClientSignature = clientSignature;
            InternalState.Status = SolverServerStates.WaitingEscape;
            return(new TrustedBroadcastRequest
            {
                Key = InternalState.FulfillKey,
                PreviousScriptPubKey = InternalState.OfferCoin.ScriptPubKey,
                Transaction = fulfill
            });
        }
Esempio n. 26
0
        /// <summary>
        /// Generates the scriptSig.
        /// </summary>
        /// <param name="signature">The transaction signature. For unsigned inputs this can be <c>null</c> in which case it is encoded as an <c>OP_0</c>.</param>
        /// <param name="coldPubKey">A flag indicating whether the cold wallet versus the hot wallet is signing.</param>
        /// <param name="publicKey">The cold or hot wallet public key.</param>
        /// <returns>The scriptSig.</returns>
        public Script GenerateScriptSig(TransactionSignature signature, bool coldPubKey, PubKey publicKey)
        {
            Guard.NotNull(signature, nameof(signature));
            Guard.NotNull(publicKey, nameof(publicKey));

            return(new Script(
                       Op.GetPushOp(signature.ToBytes()),
                       coldPubKey ? OP_0 : OP_1,
                       Op.GetPushOp(publicKey.ToBytes())
                       ));
        }
Esempio n. 27
0
        public override Script GenerateScriptSig(Network network, Script scriptPubKey, IKeyRepository keyRepo, ISigner signer)
        {
            Key key = keyRepo.FindKey(scriptPubKey);

            if (key == null)
            {
                return(null);
            }
            TransactionSignature sig = signer.Sign(key);

            return(PayToPubkeyTemplate.Instance.GenerateScriptSig(sig));
        }
Esempio n. 28
0
        public IActionResult FulfillOffer(
            [ModelBinder(BinderType = typeof(TumblerParametersModelBinder))]
            ClassicTumblerParameters tumblerId,
            int cycleId, string channelId, [FromBody] TransactionSignature signature)
        {
            if (tumblerId == null)
            {
                throw new ArgumentNullException("tumblerId");
            }
            if (signature == null)
            {
                return(BadRequest("Missing Signature"));
            }
            var session = GetSolverServerSession(cycleId, channelId, CyclePhase.TumblerCashoutPhase);
            var feeRate = Services.FeeService.GetFeeRate();

            if (session.Status != SolverServerStates.WaitingFulfillment)
            {
                return(BadRequest("invalid-state"));
            }
            try
            {
                var cycle   = GetCycle(cycleId);
                var cashout = Services.WalletService.GenerateAddress();

                var fulfill = session.FulfillOffer(signature, cashout.ScriptPubKey, feeRate);
                fulfill.BroadcastAt = new LockTime(cycle.GetPeriods().Payment.End - 1);
                Repository.Save(cycle.Start, session);

                var signedOffer = session.GetSignedOfferTransaction();
                signedOffer.BroadcastAt = fulfill.BroadcastAt - 1;
                uint correlation = GetCorrelation(session);

                var offerScriptPubKey = session.GetInternalState().OfferCoin.ScriptPubKey;
                Services.BlockExplorerService.Track(offerScriptPubKey);

                Tracker.AddressCreated(cycle.Start, TransactionType.ClientOffer, offerScriptPubKey, correlation);
                Services.TrustedBroadcastService.Broadcast(cycle.Start, TransactionType.ClientOffer, correlation, signedOffer);

                Tracker.AddressCreated(cycle.Start, TransactionType.ClientFulfill, cashout.ScriptPubKey, correlation);

                if (!Runtime.NoFulFill)
                {
                    Services.TrustedBroadcastService.Broadcast(cycle.Start, TransactionType.ClientFulfill, correlation, fulfill);
                }
                return(Json(Runtime.Cooperative ? session.GetSolutionKeys() : new SolutionKey[0]));
            }
            catch (PuzzleException ex)
            {
                return(BadRequest(ex.Message));
            }
        }
Esempio n. 29
0
        public async Task <Transaction> ReceiveAsync(ScriptCoin escrowedCoin, TransactionSignature clientSignature, Key escrowKey, FeeRate feeRate)
        {
            _ReceiveBatch.FeeRate = feeRate;
            var task = _ReceiveBatch.WaitTransactionAsync(new ClientEscapeData()
            {
                ClientSignature = clientSignature,
                EscrowedCoin    = escrowedCoin,
                EscrowKey       = escrowKey
            }).ConfigureAwait(false);

            Logs.Tumbler.LogDebug($"ClientEscape batch count {_ReceiveBatch.BatchCount}");
            return(await task);
        }
Esempio n. 30
0
        public Transaction BuildWithSignatures(TransactionSignature remotePubKeySignature)
        {
            var unsigned             = Build();
            var localPubKeySignature = SignClosingTransaction(unsigned);
            var witScript            = MultiSignatureWitnessScript.Create(
                _channel.LocalCommitmentTxParameters.FundingKey, _channel.RemoteCommitmentTxParameters.FundingKey,
                localPubKeySignature, remotePubKeySignature);

            unsigned.Inputs[0].ScriptSig = Script.Empty;
            unsigned.Inputs[0].WitScript = witScript;

            return(unsigned);
        }
Esempio n. 31
0
        public override Script GenerateScriptSig(Network network, Script scriptPubKey, IKeyRepository keyRepo, ISigner signer)
        {
            KeyId parameters = PayToPubkeyHashTemplate.Instance.ExtractScriptPubKeyParameters(scriptPubKey);
            Key   key        = keyRepo.FindKey(parameters.ScriptPubKey);

            if (key == null)
            {
                return(null);
            }
            TransactionSignature sig = signer.Sign(key);

            return(PayToPubkeyHashTemplate.Instance.GenerateScriptSig(sig, key.PubKey));
        }
Esempio n. 32
0
 public PartialSignature(PubKey pubKey, TransactionSignature signature)
 {
     if (pubKey == null)
     {
         throw new ArgumentNullException(nameof(pubKey));
     }
     if (signature == null)
     {
         throw new ArgumentNullException(nameof(signature));
     }
     Signature = signature;
     PubKey    = pubKey;
 }
Esempio n. 33
0
		public void script_combineSigs()
		{
			Key[] keys = new[] { new Key(), new Key(), new Key() };
			var txFrom = CreateCreditingTransaction(keys[0].PubKey.Hash.ScriptPubKey);
			var txTo = CreateSpendingTransaction(new Script(), txFrom);

			Script scriptPubKey = txFrom.Outputs[0].ScriptPubKey;
			Script scriptSig = txTo.Inputs[0].ScriptSig;

			Script empty = new Script();
			Script combined = Script.CombineSignatures(scriptPubKey, txTo, 0, empty, empty);
			Assert.True(combined.ToBytes().Length == 0);

			// Single signature case:
			SignSignature(keys, txFrom, txTo, 0); // changes scriptSig
			scriptSig = txTo.Inputs[0].ScriptSig;
			combined = Script.CombineSignatures(scriptPubKey, txTo, 0, scriptSig, empty);
			Assert.True(combined == scriptSig);
			combined = Script.CombineSignatures(scriptPubKey, txTo, 0, empty, scriptSig);
			Assert.True(combined == scriptSig);
			Script scriptSigCopy = scriptSig.Clone();
			// Signing again will give a different, valid signature:
			SignSignature(keys, txFrom, txTo, 0);
			scriptSig = txTo.Inputs[0].ScriptSig;

			combined = Script.CombineSignatures(scriptPubKey, txTo, 0, scriptSigCopy, scriptSig);
			Assert.True(combined == scriptSigCopy || combined == scriptSig);


			// P2SH, single-signature case:
			Script pkSingle = PayToPubkeyTemplate.Instance.GenerateScriptPubKey(keys[0].PubKey);
			scriptPubKey = pkSingle.Hash.ScriptPubKey;
			txFrom.Outputs[0].ScriptPubKey = scriptPubKey;
			txTo.Inputs[0].PrevOut = new OutPoint(txFrom, 0);

			SignSignature(keys, txFrom, txTo, 0, pkSingle);
			scriptSig = txTo.Inputs[0].ScriptSig;

			combined = Script.CombineSignatures(scriptPubKey, txTo, 0, scriptSig, empty);
			Assert.True(combined == scriptSig);

			combined = Script.CombineSignatures(scriptPubKey, txTo, 0, empty, scriptSig);
			scriptSig = txTo.Inputs[0].ScriptSig;
			Assert.True(combined == scriptSig);
			scriptSigCopy = scriptSig.Clone();

			SignSignature(keys, txFrom, txTo, 0);
			scriptSig = txTo.Inputs[0].ScriptSig;

			combined = Script.CombineSignatures(scriptPubKey, txTo, 0, scriptSigCopy, scriptSig);
			Assert.True(combined == scriptSigCopy || combined == scriptSig);
			// dummy scriptSigCopy with placeholder, should always choose non-placeholder:
			scriptSigCopy = new Script(OpcodeType.OP_0, Op.GetPushOp(pkSingle.ToBytes()));
			combined = Script.CombineSignatures(scriptPubKey, txTo, 0, scriptSigCopy, scriptSig);
			Assert.True(combined == scriptSig);
			combined = Script.CombineSignatures(scriptPubKey, txTo, 0, scriptSig, scriptSigCopy);
			Assert.True(combined == scriptSig);

			// Hardest case:  Multisig 2-of-3
			scriptPubKey = PayToMultiSigTemplate.Instance.GenerateScriptPubKey(2, keys.Select(k => k.PubKey).ToArray());
			txFrom.Outputs[0].ScriptPubKey = scriptPubKey;
			txTo.Inputs[0].PrevOut = new OutPoint(txFrom, 0);

			SignSignature(keys, txFrom, txTo, 0);
			scriptSig = txTo.Inputs[0].ScriptSig;

			combined = Script.CombineSignatures(scriptPubKey, txTo, 0, scriptSig, empty);
			Assert.True(combined == scriptSig);
			combined = Script.CombineSignatures(scriptPubKey, txTo, 0, empty, scriptSig);
			Assert.True(combined == scriptSig);

			// A couple of partially-signed versions:
			uint256 hash1 = scriptPubKey.SignatureHash(txTo, 0, SigHash.All);
			var sig1 = new TransactionSignature(keys[0].Sign(hash1), SigHash.All);

			uint256 hash2 = scriptPubKey.SignatureHash(txTo, 0, SigHash.None);
			var sig2 = new TransactionSignature(keys[1].Sign(hash2), SigHash.None);


			uint256 hash3 = scriptPubKey.SignatureHash(txTo, 0, SigHash.Single);
			var sig3 = new TransactionSignature(keys[2].Sign(hash3), SigHash.Single);


			// Not fussy about order (or even existence) of placeholders or signatures:
			Script partial1a = new Script() + OpcodeType.OP_0 + Op.GetPushOp(sig1.ToBytes()) + OpcodeType.OP_0;
			Script partial1b = new Script() + OpcodeType.OP_0 + OpcodeType.OP_0 + Op.GetPushOp(sig1.ToBytes());
			Script partial2a = new Script() + OpcodeType.OP_0 + Op.GetPushOp(sig2.ToBytes());
			Script partial2b = new Script() + Op.GetPushOp(sig2.ToBytes()) + OpcodeType.OP_0;
			Script partial3a = new Script() + Op.GetPushOp(sig3.ToBytes());
			Script partial3b = new Script() + OpcodeType.OP_0 + OpcodeType.OP_0 + Op.GetPushOp(sig3.ToBytes());
			Script partial3c = new Script() + OpcodeType.OP_0 + Op.GetPushOp(sig3.ToBytes()) + OpcodeType.OP_0;
			Script complete12 = new Script() + OpcodeType.OP_0 + Op.GetPushOp(sig1.ToBytes()) + Op.GetPushOp(sig2.ToBytes());
			Script complete13 = new Script() + OpcodeType.OP_0 + Op.GetPushOp(sig1.ToBytes()) + Op.GetPushOp(sig3.ToBytes());
			Script complete23 = new Script() + OpcodeType.OP_0 + Op.GetPushOp(sig2.ToBytes()) + Op.GetPushOp(sig3.ToBytes());

			combined = Script.CombineSignatures(scriptPubKey, txTo, 0, partial1a, partial1b);
			Assert.True(combined == partial1a);
			combined = Script.CombineSignatures(scriptPubKey, txTo, 0, partial1a, partial2a);
			Assert.True(combined == complete12);
			combined = Script.CombineSignatures(scriptPubKey, txTo, 0, partial2a, partial1a);
			Assert.True(combined == complete12);
			combined = Script.CombineSignatures(scriptPubKey, txTo, 0, partial1b, partial2b);
			Assert.True(combined == complete12);
			combined = Script.CombineSignatures(scriptPubKey, txTo, 0, partial3b, partial1b);
			Assert.True(combined == complete13);
			combined = Script.CombineSignatures(scriptPubKey, txTo, 0, partial2a, partial3a);
			Assert.True(combined == complete23);
			combined = Script.CombineSignatures(scriptPubKey, txTo, 0, partial3b, partial2b);
			Assert.True(combined == complete23);
			combined = Script.CombineSignatures(scriptPubKey, txTo, 0, partial3b, partial3a);
			Assert.True(combined == partial3c);
		}