private void Sign(TransactionSigningContext ctx, ICoin coin, IndexedTxIn txIn)
        {
            var input = txIn.TxIn;

            if (coin is StealthCoin)
            {
                var stealthCoin = (StealthCoin)coin;
                var scanKey     = FindKey(ctx, stealthCoin.Address.ScanPubKey);
                if (scanKey == null)
                {
                    throw new KeyNotFoundException("Scan key for decrypting StealthCoin not found");
                }
                var spendKeys = stealthCoin.Address.SpendPubKeys.Select(p => FindKey(ctx, p)).Where(p => p != null).ToArray();
                ctx.AdditionalKeys.AddRange(stealthCoin.Uncover(spendKeys, scanKey));
            }

            if (PayToScriptHashTemplate.Instance.CheckScriptPubKey(coin.TxOut.ScriptPubKey))
            {
                var scriptCoin = (IScriptCoin)coin;
                var original   = input.ScriptSig;
                input.ScriptSig = CreateScriptSig(ctx, scriptCoin.Redeem, txIn);
                if (original != input.ScriptSig)
                {
                    input.ScriptSig = input.ScriptSig + Op.GetPushOp(scriptCoin.Redeem.ToBytes(true));
                }
            }
            else
            {
                input.ScriptSig = CreateScriptSig(ctx, coin.TxOut.ScriptPubKey, txIn);
            }
        }
 public bool Check(PubKey pubKey, Script scriptPubKey, IndexedTxIn txIn, ScriptVerify verify = ScriptVerify.Standard)
 {
     return(Check(pubKey, scriptPubKey, txIn.Transaction, txIn.Index, verify));
 }
        private Script CreateScriptSig(TransactionSigningContext ctx, Script scriptPubKey, IndexedTxIn txIn)
        {
            var originalScriptSig = txIn.TxIn.ScriptSig;

            txIn.TxIn.ScriptSig = scriptPubKey;

            var pubKeyHashParams = PayToPubkeyHashTemplate.Instance.ExtractScriptPubKeyParameters(scriptPubKey);

            if (pubKeyHashParams != null)
            {
                var key = FindKey(ctx, pubKeyHashParams);
                if (key == null)
                {
                    return(originalScriptSig);
                }
                var sig = txIn.Sign(key, scriptPubKey, ctx.SigHash);
                return(PayToPubkeyHashTemplate.Instance.GenerateScriptSig(sig, key.PubKey));
            }

            var multiSigParams = PayToMultiSigTemplate.Instance.ExtractScriptPubKeyParameters(scriptPubKey);

            if (multiSigParams != null)
            {
                var alreadySigned = PayToMultiSigTemplate.Instance.ExtractScriptSigParameters(originalScriptSig);
                if (alreadySigned == null && !Script.IsNullOrEmpty(originalScriptSig))                //Maybe a P2SH
                {
                    var ops = originalScriptSig.ToOps().ToList();
                    ops.RemoveAt(ops.Count - 1);
                    alreadySigned = PayToMultiSigTemplate.Instance.ExtractScriptSigParameters(new Script(ops));
                }
                List <TransactionSignature> signatures = new List <TransactionSignature>();
                if (alreadySigned != null)
                {
                    signatures.AddRange(alreadySigned);
                }
                var keys =
                    multiSigParams
                    .PubKeys
                    .Select(p => FindKey(ctx, p))
                    .ToArray();

                int sigCount = signatures.Where(s => s != TransactionSignature.Empty && s != null).Count();
                for (int i = 0; i < keys.Length; i++)
                {
                    if (sigCount == multiSigParams.SignatureCount)
                    {
                        break;
                    }

                    if (i >= signatures.Count)
                    {
                        signatures.Add(null);
                    }
                    if (keys[i] != null)
                    {
                        var sig = txIn.Sign(keys[i], scriptPubKey, ctx.SigHash);
                        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));
            }

            var pubKeyParams = PayToPubkeyTemplate.Instance.ExtractScriptPubKeyParameters(scriptPubKey);

            if (pubKeyParams != null)
            {
                var key = FindKey(ctx, pubKeyParams);
                if (key == null)
                {
                    return(originalScriptSig);
                }
                var sig = txIn.Sign(key, scriptPubKey, ctx.SigHash);
                return(PayToPubkeyTemplate.Instance.GenerateScriptSig(sig));
            }

            throw new NotSupportedException("Unsupported scriptPubKey");
        }
Exemple #4
0
 public bool Check(Network network, PubKey pubKey, Script scriptPubKey, IndexedTxIn txIn, ScriptVerify verify = ScriptVerify.Standard)
 {
     return(this.Check(network, pubKey, scriptPubKey, txIn.Transaction, txIn.Index, verify));
 }