예제 #1
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());
            }
        }
예제 #2
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);
                }
            }
        }
예제 #3
0
        public override void Finalize(InputSigningContext inputSigningContext)
        {
            var txIn           = inputSigningContext.Input;
            var scriptPubKey   = inputSigningContext.Coin.GetScriptCode();
            var multiSigParams = PayToMultiSigTemplate.Instance.ExtractScriptPubKeyParameters(scriptPubKey);

            if (multiSigParams.SignatureCount > txIn.PartialSigs.Count)
            {
                return;
            }
            List <TransactionSignature> sigs = new List <TransactionSignature>();
            int sigcount = 0;

            foreach (var pk in multiSigParams.PubKeys)
            {
                if (sigcount == multiSigParams.SignatureCount)
                {
                    break;
                }
                if (txIn.PartialSigs.TryGetValue(pk, out var s))
                {
                    sigcount++;
                    sigs.Add(s);
                }
            }
            txIn.FinalScriptSig = PayToMultiSigTemplate.Instance.GenerateScriptSig(sigs.ToArray());
        }
예제 #4
0
        public override void Finalize(InputSigningContext inputSigningContext)
        {
            var txIn = inputSigningContext.Input;

            if (txIn.TaprootInternalKey is TaprootInternalPubKey &&
                txIn.TaprootKeySignature is TaprootSignature)
            {
                txIn.FinalScriptWitness = PayToTaprootTemplate.Instance.GenerateWitScript(txIn.TaprootKeySignature);
            }
        }
        public override void Finalize(InputSigningContext inputSigningContext)
        {
            var txIn = inputSigningContext.Input;

            if (txIn.PartialSigs.Count is 0)
            {
                return;
            }
            var sig = txIn.PartialSigs.First();

            txIn.FinalScriptSig = PayToPubkeyHashTemplate.Instance.GenerateScriptSig(sig.Value, sig.Key);
        }
        public override void Finalize(InputSigningContext inputSigningContext)
        {
            var txIn         = inputSigningContext.Input;
            var scriptPubKey = inputSigningContext.Coin.GetScriptCode();
            var pk           = PayToPubkeyTemplate.Instance.ExtractScriptPubKeyParameters(scriptPubKey);

            if (!txIn.PartialSigs.TryGetValue(pk, out var sig))
            {
                return;
            }
            txIn.FinalScriptSig = PayToPubkeyTemplate.Instance.GenerateScriptSig(sig);
        }
        public override void Sign(InputSigningContext inputSigningContext, IKeyRepository keyRepository, ISigner signer)
        {
            var scriptCode = inputSigningContext.Coin.GetScriptCode();
            var key        = keyRepository.FindKey(scriptCode) as PubKey;

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

            if (sig is null)
            {
                return;
            }
            inputSigningContext.Input.PartialSigs.TryAdd(key, sig);
        }
예제 #8
0
        public override void Sign(InputSigningContext inputSigningContext, IKeyRepository keyRepository, ISigner signer)
        {
            var pk = keyRepository.FindKey(inputSigningContext.Coin.TxOut.ScriptPubKey) as TaprootFullPubKey;

            if (pk is null)
            {
                return;
            }
            var signature = signer.Sign(pk) as TaprootSignature;

            if (signature is null)
            {
                return;
            }
            inputSigningContext.Input.TaprootInternalKey  = pk.InternalKey;
            inputSigningContext.Input.TaprootKeySignature = signature;
            inputSigningContext.Input.TaprootMerkleRoot   = pk.MerkleRoot;
        }
        public override void Sign(InputSigningContext inputSigningContext, IKeyRepository keyRepository, ISigner signer)
        {
            var executedScript = inputSigningContext.Coin.GetScriptCode();
            var parameters     = PayToPubkeyHashTemplate.Instance.ExtractScriptPubKeyParameters(executedScript);
            var key            = keyRepository.FindKey(parameters.ScriptPubKey) as PubKey;

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

            if (sig is null)
            {
                return;
            }
            inputSigningContext.Input.PartialSigs.TryAdd(key, sig);
        }
        public override void ExtractExistingSignatures(InputSigningContext inputSigningContext)
        {
            var    scriptPubKey      = inputSigningContext.Coin.GetScriptCode();
            var    scriptSigData     = inputSigningContext.OriginalTxIn.ScriptSig.ToOps().Select(o => o.PushData);
            var    witScriptData     = inputSigningContext.OriginalTxIn.WitScript.Pushes;
            PubKey pk                = null;
            TransactionSignature sig = null;

            foreach (var data in scriptSigData.Concat(witScriptData))
            {
                if (data is null)
                {
                    continue;
                }
                if (data.Length == 65 || data.Length == 33)
                {
                    try
                    {
                        pk = new PubKey(data);
                    }
                    catch { }
                }
                else
                {
                    try
                    {
                        sig = new TransactionSignature(data);
                    }
                    catch
                    {
                    }
                }
                if (sig is TransactionSignature && pk is PubKey)
                {
                    inputSigningContext.Input.PartialSigs.TryAdd(pk, sig);
                }
            }
        }
        public override void ExtractExistingSignatures(InputSigningContext inputSigningContext)
        {
            var scriptPubKey  = inputSigningContext.Coin.GetScriptCode();
            var pk            = PayToPubkeyTemplate.Instance.ExtractScriptPubKeyParameters(scriptPubKey);
            var scriptSigData = inputSigningContext.OriginalTxIn.ScriptSig.ToOps().Select(o => o.PushData);
            var witScriptData = inputSigningContext.OriginalTxIn.WitScript.Pushes;

            foreach (var data in scriptSigData.Concat(witScriptData))
            {
                if (data is null)
                {
                    continue;
                }
                try
                {
                    var sig = new TransactionSignature(data);
                    inputSigningContext.Input.PartialSigs.TryAdd(pk, sig);
                    break;
                }
                catch
                {
                }
            }
        }
예제 #12
0
 public abstract void Sign(InputSigningContext inputSigningContext, IKeyRepository keyRepository, ISigner signer);
예제 #13
0
 public virtual void ExtractExistingSignatures(InputSigningContext inputSigningContext)
 {
 }
예제 #14
0
 public virtual void MergePartialSignatures(InputSigningContext inputSigningContext)
 {
 }
예제 #15
0
        public override void ExtractExistingSignatures(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();

            bool          hasRedeem;
            List <byte[]> sigs;

            if (inputSigningContext.Coin is ScriptCoin scriptCoin)
            {
                hasRedeem = true;
                if (scriptCoin.RedeemType == RedeemType.P2SH)
                {
                    if (Script.IsNullOrEmpty(inputSigningContext.OriginalTxIn.ScriptSig))
                    {
                        return;
                    }
                    sigs = scriptSig.ToOps().Select(s => s.PushData).ToList();
                }
                else                 // if (scriptCoin.RedeemType == RedeemType.WitnessV0)
                {
                    if (WitScript.IsNullOrEmpty(inputSigningContext.OriginalTxIn.WitScript))
                    {
                        return;
                    }
                    sigs = witScript.Pushes.ToList();
                }
            }
            else
            {
                hasRedeem = false;
                sigs      = scriptSig.ToOps().Select(s => s.PushData).ToList();
            }
            // At least leading 0, pk count and the redeem
            if (sigs.Count < 2 + (hasRedeem ? 1 : 0))
            {
                return;
            }
            if (!(sigs[0]?.Length is 0))
            {
                return;
            }
            sigs.RemoveAt(0);             // Remove leading 0
            if (hasRedeem)
            {
                sigs.RemoveAt(sigs.Count - 1);                 // Remove the redeem
            }
            int pkIndex = 0;

            for (int i = 0; i < sigs.Count && pkIndex < multiSigParams.PubKeys.Length; i++)
            {
                var sig = sigs[i];
                var pk  = multiSigParams.PubKeys[pkIndex];
                if (sig.Length is 0)
                {
                    pkIndex++;
                }
                else
                {
                    try
                    {
                        var txsig = new TransactionSignature(sig);
                        var hash  = inputSigningContext.TransactionContext
                                    .Transaction
                                    .Inputs.FindIndexedInput(inputSigningContext.Coin.Outpoint)
                                    .GetSignatureHash(inputSigningContext.Coin, txsig.SigHash, inputSigningContext.TransactionContext.SigningOptions.PrecomputedTransactionData);
                        while (!pk.Verify(hash, txsig.Signature))
                        {
                            pkIndex++;
                            if (pkIndex >= multiSigParams.PubKeys.Length)
                            {
                                goto end;
                            }
                            pk = multiSigParams.PubKeys[pkIndex];
                        }
                        txIn.PartialSigs.TryAdd(pk, txsig);
                        pkIndex++;
                    }
                    catch { }
                }
            }
            end:;
        }
 public override void Sign(InputSigningContext inputSigningContext, IKeyRepository keyRepository, ISigner signer)
 {
 }
 public override void Finalize(InputSigningContext inputSigningContext)
 {
     inputSigningContext.Input.FinalScriptSig = Script.Empty;
 }
예제 #18
0
 public abstract void Finalize(InputSigningContext inputSigningContext);