Exemplo n.º 1
0
        private static Script CombineSignatures(Script scriptPubKey, TransactionChecker checker, byte[][] sigs1, byte[][] sigs2, HashVersion hashVersion)
        {
            var template = StandardScripts.GetTemplateFromScriptPubKey(scriptPubKey);

            if (template is PayToWitPubKeyHashTemplate)
            {
                scriptPubKey = new KeyId(scriptPubKey.ToBytes(true).SafeSubarray(1, 20)).ScriptPubKey;
                template     = StandardScripts.GetTemplateFromScriptPubKey(scriptPubKey);
            }
            if (template == null || template is TxNullDataTemplate)
            {
                return(PushAll(Max(sigs1, sigs2)));
            }

            if (template is PayToPubkeyTemplate || template is PayToPubkeyHashTemplate)
            {
                if (sigs1.Length == 0 || sigs1[0].Length == 0)
                {
                    return(PushAll(sigs2));
                }
                else
                {
                    return(PushAll(sigs1));
                }
            }
            if (template is PayToScriptHashTemplate || template is PayToWitTemplate)
            {
                if (sigs1.Length == 0 || sigs1[sigs1.Length - 1].Length == 0)
                {
                    return(PushAll(sigs2));
                }

                if (sigs2.Length == 0 || sigs2[sigs2.Length - 1].Length == 0)
                {
                    return(PushAll(sigs1));
                }

                var redeemBytes = sigs1[sigs1.Length - 1];
                var redeem      = new Script(redeemBytes);
                sigs1 = sigs1.Take(sigs1.Length - 1).ToArray();
                sigs2 = sigs2.Take(sigs2.Length - 1).ToArray();
                Script result = CombineSignatures(redeem, checker, sigs1, sigs2, hashVersion);
                result += Op.GetPushOp(redeemBytes);
                return(result);
            }

            if (template is PayToMultiSigTemplate)
            {
                return(CombineMultisig(scriptPubKey, checker, sigs1, sigs2, hashVersion));
            }

            return(null);
        }
Exemplo n.º 2
0
 public ScriptTemplate FindTemplate()
 {
     return(StandardScripts.GetTemplateFromScriptPubKey(this));
 }
Exemplo n.º 3
0
        public bool IsRelevantAndUpdate(Transaction tx)
        {
            if (tx == null)
            {
                throw new ArgumentNullException("tx");
            }
            var  hash   = tx.GetHash();
            bool fFound = false;

            // Match if the filter contains the hash of tx
            //  for finding tx when they appear in a block
            if (isFull)
            {
                return(true);
            }
            if (isEmpty)
            {
                return(false);
            }
            if (Contains(hash))
            {
                fFound = true;
            }

            for (uint i = 0; i < tx.Outputs.Count; i++)
            {
                TxOut txout = tx.Outputs[(int)i];
                // Match if the filter contains any arbitrary script data element in any scriptPubKey in tx
                // If this matches, also add the specific output that was matched.
                // This means clients don't have to update the filter themselves when a new relevant tx
                // is discovered in order to find spending transactions, which avoids round-tripping and race conditions.
                foreach (Op op in txout.ScriptPubKey.ToOps())
                {
                    if (op.PushData != null && op.PushData.Length != 0 && Contains(op.PushData))
                    {
                        fFound = true;
                        if ((nFlags & (byte)BloomFlags.UPDATE_MASK) == (byte)BloomFlags.UPDATE_ALL)
                        {
                            Insert(new OutPoint(hash, i));
                        }
                        else if ((nFlags & (byte)BloomFlags.UPDATE_MASK) == (byte)BloomFlags.UPDATE_P2PUBKEY_ONLY)
                        {
                            var template = StandardScripts.GetTemplateFromScriptPubKey(txout.ScriptPubKey);
                            if (template != null &&
                                (template.Type == TxOutType.TX_PUBKEY || template.Type == TxOutType.TX_MULTISIG))
                            {
                                Insert(new OutPoint(hash, i));
                            }
                        }
                        break;
                    }
                }
            }

            if (fFound)
            {
                return(true);
            }

            foreach (TxIn txin in tx.Inputs)
            {
                // Match if the filter contains an outpoint tx spends
                if (Contains(txin.PrevOut))
                {
                    return(true);
                }

                // Match if the filter contains any arbitrary script data element in any scriptSig in tx
                foreach (Op op in txin.ScriptSig.ToOps())
                {
                    if (op.PushData != null && op.PushData.Length != 0 && Contains(op.PushData))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }