コード例 #1
0
		public bool Check(PubKey pubKey, Script scriptPubKey, Transaction tx, uint nIndex, ScriptVerify verify = ScriptVerify.Standard)
		{
			return new ScriptEvaluationContext()
			{
				ScriptVerify = verify,
				SigHash = SigHash
			}.CheckSig(this, pubKey, scriptPubKey, tx, nIndex);
		}
コード例 #2
0
		/// <summary>
		/// Check if valid transaction signature
		/// </summary>
		/// <param name="sig">The signature</param>
		/// <param name="scriptVerify">Verification rules</param>
		/// <param name="error">Error</param>
		/// <returns>True if valid</returns>
		public static bool IsValid(byte[] sig, ScriptVerify scriptVerify, out ScriptError error)
		{
			if(sig == null)
				throw new ArgumentNullException("sig");
			if(sig.Length == 0)
			{
				error = ScriptError.SigDer;
				return false;
			}
			error = ScriptError.OK;
			var ctx = new ScriptEvaluationContext()
			{
				ScriptVerify = scriptVerify
			};
			if(!ctx.CheckSignatureEncoding(sig))
			{
				error = ctx.Error;
				return false;
			}
			return true;
		}
コード例 #3
0
		private bool VerifyScript(IndexedTxIn input, Script scriptPubKey, ScriptVerify scriptVerify, out ScriptError error)
		{
			if(!UseConsensusLib)
				return input.VerifyScript(scriptPubKey, scriptVerify, out error);
			else
			{
				var ok = Script.VerifyScriptConsensus(scriptPubKey, input.Transaction, input.Index, scriptVerify);
				if(!ok)
				{
					if(input.VerifyScript(scriptPubKey, scriptVerify, out error))
						error = ScriptError.UnknownError;
					return false;
				}
				else
				{
					error = ScriptError.OK;
				}
				return true;
			}
		}
コード例 #4
0
		public bool Check(PubKey pubKey, Script scriptPubKey, IndexedTxIn txIn, ScriptVerify verify = ScriptVerify.Standard)
		{
			return Check(pubKey, scriptPubKey, txIn.Transaction, txIn.Index, verify);
		}
コード例 #5
0
 private static extern int VerifyScriptConsensusWithAmount(byte[] scriptPubKey, uint scriptPubKeyLen, long amount, byte[] txTo, uint txToLen, uint nIn, ScriptVerify flags, ref BitcoinConsensusError err);
コード例 #6
0
        public static bool VerifyScript(Script scriptPubKey, Transaction tx, int i, Money value, ScriptVerify scriptVerify, SigHash sigHash, out ScriptError error)
        {
            var scriptSig = tx.Inputs[i].ScriptSig;

            return(VerifyScript(scriptSig, scriptPubKey, tx, i, value, scriptVerify, sigHash, out error));
        }
コード例 #7
0
 public static bool VerifyScript(Script scriptSig, Script scriptPubKey, Transaction tx, int i, ScriptVerify scriptVerify = ScriptVerify.Standard, SigHash sigHash = SigHash.Undefined)
 {
     return(VerifyScript(scriptSig, scriptPubKey, tx, i, null, scriptVerify, sigHash, out ScriptError unused));
 }
コード例 #8
0
ファイル: Script.cs プロジェクト: woutersmit/NBitcoin
		private static extern int VerifyScriptConsensus(byte[] scriptPubKey, uint scriptPubKeyLen, byte[] txTo, uint txToLen, uint nIn, ScriptVerify flags, ref BitcoinConsensusError err);
コード例 #9
0
ファイル: script_tests.cs プロジェクト: vebin/NBitcoin
		private void AssertValidScript(Script scriptPubKey, Transaction tx, int n, ScriptVerify verify)
		{
			Assert.True(Script.VerifyScript(scriptPubKey, tx, n, flags));
#if !NOCONSENSUSLIB
			Assert.True(Script.VerifyScriptConsensus(scriptPubKey, tx, (uint)n, flags));
#endif
		}
コード例 #10
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));
 }
コード例 #11
0
		/// <summary>
		/// Check if valid transaction signature
		/// </summary>
		/// <param name="sig">Signature in bytes</param>
		/// <param name="scriptVerify">Verification rules</param>
		/// <returns>True if valid</returns>
		public static bool IsValid(byte[] sig, ScriptVerify scriptVerify = ScriptVerify.DerSig | ScriptVerify.StrictEnc)
		{
			ScriptError error;
			return IsValid(sig, scriptVerify, out error);
		}
コード例 #12
0
        /// <inheritdoc/>
        public bool VerifySignature(UnspentOutputs coin, Transaction txTo, int txToInN, ScriptVerify flagScriptVerify)
        {
            TxIn input = txTo.Inputs[txToInN];

            if (input.PrevOut.N >= coin.Outputs.Length)
            {
                this.logger.LogTrace("(-)[OUTPUT_INCORRECT_LENGTH]");
                return(false);
            }

            if (input.PrevOut.Hash != coin.TransactionId)
            {
                this.logger.LogTrace("(-)[INCORRECT_TX]");
                return(false);
            }

            TxOut output = coin.Outputs[input.PrevOut.N];

            if (output == null)
            {
                this.logger.LogTrace("(-)[OUTPUT_NOT_FOUND]");
                return(false);
            }

            var txData  = new PrecomputedTransactionData(txTo);
            var checker = new TransactionChecker(txTo, txToInN, output.Value, txData);
            var ctx     = new ScriptEvaluationContext(this.chain.Network)
            {
                ScriptVerify = flagScriptVerify
            };

            bool res = ctx.VerifyScript(input.ScriptSig, output.ScriptPubKey, checker);

            return(res);
        }
コード例 #13
0
ファイル: Script.cs プロジェクト: dgmib/NBitcoin
        public static bool VerifyScriptConsensus(Script scriptPubKey, Transaction tx, uint nIn, ScriptVerify flags)
        {
            var scriptPubKeyBytes = scriptPubKey.ToBytes();
            var txToBytes         = tx.ToBytes();

            var err   = BitcoinConsensusError.ERR_OK;
            var valid = VerifyScriptConsensus(scriptPubKeyBytes, (uint)scriptPubKeyBytes.Length, txToBytes, (uint)txToBytes.Length, nIn, flags, ref err);

            return(valid == 1);
        }
コード例 #14
0
        public static bool VerifyScript(Script scriptSig, Script scriptPubKey, Transaction tx, int i, ScriptVerify scriptVerify = ScriptVerify.StrictEnc | ScriptVerify.P2SH, SigHash sigHash = SigHash.Undefined)
        {
            ScriptEvaluationContext eval = new ScriptEvaluationContext();

            eval.SigHash      = sigHash;
            eval.ScriptVerify = scriptVerify;
            return(eval.VerifyScript(scriptSig, scriptPubKey, tx, i));
        }
コード例 #15
0
ファイル: Script.cs プロジェクト: knocte/NBitcoin
		public static bool VerifyScript(Script scriptSig, Script scriptPubKey, Transaction tx, int i, Money value, ScriptVerify scriptVerify = ScriptVerify.Standard, SigHash sigHash = SigHash.Undefined)
		{
			ScriptError unused;
			return VerifyScript(scriptSig, scriptPubKey, tx, i, value, scriptVerify, sigHash, out unused);
		}
コード例 #16
0
ファイル: transaction_tests.cs プロジェクト: knocte/NBitcoin
		void CheckWithFlag(Transaction output, Transaction input, ScriptVerify flags, bool success)
		{
			Transaction inputi = input.Clone();
			ScriptEvaluationContext ctx = new ScriptEvaluationContext();
			ctx.ScriptVerify = flags;
			bool ret = ctx.VerifyScript(inputi.Inputs[0].ScriptSig, output.Outputs[0].ScriptPubKey, new TransactionChecker(inputi, 0, output.Outputs[0].Value));
			Assert.True(ret == success);
		}
コード例 #17
0
 public bool Check(Network network, PubKey pubKey, Script scriptPubKey, Transaction tx, uint nIndex, ScriptVerify verify = ScriptVerify.Standard)
 {
     return(new ScriptEvaluationContext(network)
     {
         ScriptVerify = verify,
         SigHash = SigHash
     }.CheckSig(this, pubKey, scriptPubKey, tx, nIndex));
 }
コード例 #18
0
ファイル: Script.cs プロジェクト: woutersmit/NBitcoin
		public static bool VerifyScript(Script scriptPubKey, Transaction tx, int i, ScriptVerify scriptVerify, SigHash sigHash, out ScriptError error)
		{
			var scriptSig = tx.Inputs[i].ScriptSig;
			return VerifyScript(scriptSig, scriptPubKey, tx, i, scriptVerify, sigHash, out error);
		}
コード例 #19
0
        /// <inheritdoc/>
        public bool VerifySignature(UnspentOutput coin, Transaction txTo, int txToInN, ScriptVerify flagScriptVerify)
        {
            Guard.NotNull(coin, nameof(coin));
            Guard.NotNull(txTo, nameof(txTo));

            if (txToInN < 0 || txToInN >= txTo.Inputs.Count)
            {
                return(false);
            }

            TxIn input = txTo.Inputs[txToInN];

            //if (input.PrevOut.N >= coin.Outputs.Length)
            //{
            //    this.logger.LogTrace("(-)[OUTPUT_INCORRECT_LENGTH]");
            //    return false;
            //}

            //if (input.PrevOut.Hash != coin.TransactionId)
            if (input.PrevOut.Hash != coin.OutPoint.Hash)
            {
                this.logger.LogTrace("(-)[INCORRECT_TX]");
                return(false);
            }

            TxOut output = coin.Coins.TxOut;//.Outputs[input.PrevOut.N];

            if (output == null)
            {
                this.logger.LogTrace("(-)[OUTPUT_NOT_FOUND]");
                return(false);
            }

            var txData  = new PrecomputedTransactionData(txTo);
            var checker = new TransactionChecker(txTo, txToInN, output.Value, txData);
            var ctx     = new ScriptEvaluationContext(this.chainIndexer.Network)
            {
                ScriptVerify = flagScriptVerify
            };

            bool res = ctx.VerifyScript(input.ScriptSig, output.ScriptPubKey, checker);

            return(res);
        }
コード例 #20
0
 public bool Check(PubKey pubKey, Script scriptPubKey, IndexedTxIn txIn, ScriptVerify verify = ScriptVerify.Standard)
 {
     return(Check(pubKey, scriptPubKey, txIn.Transaction, txIn.Index, verify));
 }
コード例 #21
0
        private bool VerifySignature(UnspentOutputs txFrom, Transaction txTo, int txToInN, ScriptVerify flagScriptVerify)
        {
            var input = txTo.Inputs[txToInN];

            if (input.PrevOut.N >= txFrom._Outputs.Length)
            {
                return(false);
            }

            if (input.PrevOut.Hash != txFrom.TransactionId)
            {
                return(false);
            }

            var output = txFrom._Outputs[input.PrevOut.N];

            var txData  = new PrecomputedTransactionData(txTo);
            var checker = new TransactionChecker(txTo, txToInN, output.Value, txData);
            var ctx     = new ScriptEvaluationContext {
                ScriptVerify = flagScriptVerify
            };

            return(ctx.VerifyScript(input.ScriptSig, output.ScriptPubKey, checker));
        }
コード例 #22
0
        public static bool VerifyScript(Script scriptPubKey, Transaction tx, int i, Money value, ScriptVerify scriptVerify = ScriptVerify.Standard, SigHash sigHash = SigHash.Undefined)
        {
            var scriptSig = tx.Inputs[i].ScriptSig;

            return(VerifyScript(scriptSig, scriptPubKey, tx, i, value, scriptVerify, sigHash, out ScriptError unused));
        }
コード例 #23
0
ファイル: Script.cs プロジェクト: nikropht/NBitcoin
 public static bool VerifyScript(Script scriptSig, Script scriptPubKey, Transaction tx, int i, ScriptVerify scriptVerify = ScriptVerify.StrictEnc | ScriptVerify.P2SH, SigHash sigHash = SigHash.Undefined)
 {
     ScriptEvaluationContext eval = new ScriptEvaluationContext();
     eval.SigHash = sigHash;
     eval.ScriptVerify = scriptVerify;
     return eval.VerifyScript(scriptSig, scriptPubKey, tx, i);
 }
コード例 #24
0
        public static bool VerifyScript(Script scriptSig, Script scriptPubKey, Transaction tx, int i, Money value, ScriptVerify scriptVerify, SigHash sigHash, out ScriptError error)
        {
            var eval = new ScriptEvaluationContext
            {
                SigHash      = sigHash,
                ScriptVerify = scriptVerify
            };
            var result = eval.VerifyScript(scriptSig, scriptPubKey, tx, i, value);

            error = eval.Error;
            return(result);
        }
コード例 #25
0
        private bool VerifyScript(IndexedTxIn input, Script scriptPubKey, Money value, ScriptVerify scriptVerify,
                                  out ScriptError error)
        {
#if !NOCONSENSUSLIB
            if (!UseConsensusLib)
#endif
            {
                if (input.Transaction is IHasForkId)
                {
                    scriptVerify |= Scripting.ScriptVerify.ForkId;
                }

                return(input.VerifyScript(scriptPubKey, value, scriptVerify, out error));
            }
#if !NOCONSENSUSLIB
            if (input.Transaction is IHasForkId)
            {
                scriptVerify |= (ScriptVerify)(1U << 16);
            }

            var ok = Script.VerifyScriptConsensus(scriptPubKey, input.Transaction, input.Index, scriptVerify);
            if (!ok)
            {
                if (input.VerifyScript(scriptPubKey, scriptVerify, out error))
                {
                    error = ScriptError.UnknownError;
                }

                return(false);
            }

            error = ScriptError.OK;
            return(true);
#endif
        }
コード例 #26
0
		private bool VerifyScript(IndexedTxIn input, Script scriptPubKey, Money value, ScriptVerify scriptVerify, out ScriptError error)
		{
#if !NOCONSENSUSLIB
			if(!UseConsensusLib)
#endif
				return input.VerifyScript(scriptPubKey, value, scriptVerify, out error);
#if !NOCONSENSUSLIB
			else
			{
				var ok = Script.VerifyScriptConsensus(scriptPubKey, input.Transaction, input.Index, scriptVerify);
				if(!ok)
				{
					if(input.VerifyScript(scriptPubKey, scriptVerify, out error))
						error = ScriptError.UnknownError;
					return false;
				}
				else
				{
					error = ScriptError.OK;
				}
				return true;
			}
#endif
		}
コード例 #27
0
        private bool VerifyScript(IndexedTxIn input, Script scriptPubKey, Money value, ScriptVerify scriptVerify, out ScriptError error)
        {
#if !NOCONSENSUSLIB
            if (!UseConsensusLib)
#endif
            return(input.VerifyScript(scriptPubKey, value, scriptVerify, out error));

#if !NOCONSENSUSLIB
            else
            {
                var ok = Script.VerifyScriptConsensus(scriptPubKey, input.Transaction, input.Index, scriptVerify);
                if (!ok)
                {
                    if (input.VerifyScript(scriptPubKey, scriptVerify, out error))
                    {
                        error = ScriptError.UnknownError;
                    }
                    return(false);
                }
                else
                {
                    error = ScriptError.OK;
                }
                return(true);
            }
#endif
        }
コード例 #28
0
        /// <inheritdoc/>
        public bool VerifySignature(UnspentOutputs coin, Transaction txTo, int txToInN, ScriptVerify flagScriptVerify)
        {
            TxIn input = txTo.Inputs[txToInN];

            if (input.PrevOut.N >= coin.Outputs.Length)
            {
                return(false);
            }

            if (input.PrevOut.Hash != coin.TransactionId)
            {
                return(false);
            }

            TxOut output = coin.Outputs[input.PrevOut.N];

            var txData  = new PrecomputedTransactionData(txTo);
            var checker = new TransactionChecker(txTo, txToInN, output.Value, txData);
            var ctx     = new ScriptEvaluationContext(this.chain.Network)
            {
                ScriptVerify = flagScriptVerify
            };

            bool res = ctx.VerifyScript(input.ScriptSig, output.ScriptPubKey, checker);

            return(res);
        }
コード例 #29
0
        public static bool VerifyScriptConsensus(Script scriptPubKey, Transaction tx, uint nIn, Money amount, ScriptVerify flags)
        {
            var err = BitcoinConsensusError.ERR_OK;

            return(VerifyScriptConsensus(scriptPubKey, tx, nIn, amount, flags, out err));
        }
コード例 #30
0
		public ScriptPolicyError(IndexedTxIn input, ScriptError error, ScriptVerify scriptVerify, Script scriptPubKey)
			: base("Script error on input " + input.Index + " (" + error + ")", input)
		{
			_ScriptError = error;
			_ScriptVerify = scriptVerify;
			_ScriptPubKey = scriptPubKey;
		}
コード例 #31
0
        public static bool VerifyScriptConsensus(Script scriptPubKey, Transaction tx, uint nIn, Money amount, ScriptVerify flags, out BitcoinConsensusError err)
        {
            var scriptPubKeyBytes = scriptPubKey.ToBytes();
            var txToBytes         = tx.ToBytes();

            err = BitcoinConsensusError.ERR_OK;
            var valid = VerifyScriptConsensusWithAmount(scriptPubKeyBytes, (uint)scriptPubKeyBytes.Length, amount.Satoshi, txToBytes, (uint)txToBytes.Length, nIn, flags, ref err);

            return(valid == 1);
        }
コード例 #32
0
ファイル: transaction_tests.cs プロジェクト: knocte/NBitcoin
		private void AssertCorrectlySigned(Transaction tx, Script scriptPubKey, ScriptVerify scriptVerify = ScriptVerify.Standard)
		{
			for(int i = 0 ; i < tx.Inputs.Count ; i++)
			{
				Assert.True(Script.VerifyScript(scriptPubKey, tx, i, null, scriptVerify));
			}
		}
コード例 #33
0
        /// <summary>
        /// Verifies transaction's signature.
        /// </summary>
        /// <param name="coin">UTXO that is spent in the transaction.</param>
        /// <param name="txTo">Transaction.</param>
        /// <param name="txToInN">Index of the transaction's input.</param>
        /// <param name="flagScriptVerify">Script verification flags.</param>
        /// <returns><c>true</c> if signature is valid.</returns>
        private bool VerifySignature(UnspentOutputs coin, Transaction txTo, int txToInN, ScriptVerify flagScriptVerify)
        {
            this.logger.LogTrace("({0}:'{1}/{2}',{3}:{4},{5}:{6})", nameof(coin), coin.TransactionId, coin.Height, nameof(txToInN), txToInN, nameof(flagScriptVerify), flagScriptVerify);

            TxIn input = txTo.Inputs[txToInN];

            if (input.PrevOut.N >= coin.Outputs.Length)
            {
                return(false);
            }

            if (input.PrevOut.Hash != coin.TransactionId)
            {
                return(false);
            }

            TxOut output = coin.Outputs[input.PrevOut.N];

            var txData  = new PrecomputedTransactionData(txTo);
            var checker = new TransactionChecker(txTo, txToInN, output.Value, txData);
            var ctx     = new ScriptEvaluationContext {
                ScriptVerify = flagScriptVerify
            };

            bool res = ctx.VerifyScript(input.ScriptSig, output.ScriptPubKey, checker);

            this.logger.LogTrace("(-):{0}", res);
            return(res);
        }
コード例 #34
0
ファイル: script_tests.cs プロジェクト: vebin/NBitcoin
		private void AssertVerifyScript(Script scriptSig, Script scriptPubKey, ScriptVerify flags, int testIndex, string comment, bool expected)
		{
			var creditingTransaction = CreateCreditingTransaction(scriptPubKey);
			var spendingTransaction = CreateSpendingTransaction(scriptSig, creditingTransaction);

			var actual = Script.VerifyScript(scriptSig, scriptPubKey, spendingTransaction, 0, flags, SigHash.Undefined);
			Assert.True(expected == actual, "Test : " + testIndex + " " + comment);

#if !NOCONSENSUSLIB
			actual = Script.VerifyScriptConsensus(scriptPubKey, spendingTransaction, 0, flags);
			Assert.True(expected == actual, "[ConsensusLib] Test : " + testIndex + " " + comment);
#endif
		}
コード例 #35
0
ファイル: DeploymentFlags.cs プロジェクト: glasgowdev/purple
        public DeploymentFlags(ChainedBlock nextBlock, ThresholdState[] prevBlockStates, Consensus chainparams, ConcurrentChain chain)
        {
            // Do not allow blocks that contain transactions which 'overwrite' older transactions,
            // unless those are already completely spent.
            // If such overwrites are allowed, coinbases and transactions depending upon those
            // can be duplicated to remove the ability to spend the first instance -- even after
            // being sent to another address.
            // See BIP30 and http://r6.ca/blog/20120206T005236Z.html for more information.
            // This logic is not necessary for memory pool transactions, as AcceptToMemoryPool
            // already refuses previously-known transaction ids entirely.
            // This rule was originally applied to all blocks with a timestamp after March 15, 2012, 0:00 UTC.
            // Now that the whole chain is irreversibly beyond that time it is applied to all blocks except the
            // two in the chain that violate it. This prevents exploiting the issue against nodes during their
            // initial block download.
            this.EnforceBIP30 = (nextBlock.HashBlock == null) || // Enforce on CreateNewBlock invocations which don't have a hash.
                                !((nextBlock.Height == 91842 && nextBlock.HashBlock == new uint256("00000000000a4d0a398161ffc163c503763b1f4360639393e0e4c8e300e0caec")) ||
                                  (nextBlock.Height == 91880 && nextBlock.HashBlock == new uint256("00000000000743f190a18c5577a3c2d2a1f610ae9601ac046a38084ccb7cd721")));

            // Once BIP34 activated it was not possible to create new duplicate coinbases and thus other than starting
            // with the 2 existing duplicate coinbase pairs, not possible to create overwriting txs.  But by the
            // time BIP34 activated, in each of the existing pairs the duplicate coinbase had overwritten the first
            // before the first had been spent.  Since those coinbases are sufficiently buried its no longer possible to create further
            // duplicate transactions descending from the known pairs either.
            // If we're on the known chain at height greater than where BIP34 activated, we can save the db accesses needed for the BIP30 check.
            ChainedBlock bip34HeightChainedBlock = chain.GetBlock(chainparams.BuriedDeployments[BuriedDeployments.BIP34]);

            //Only continue to enforce if we're below BIP34 activation height or the block hash at that height doesn't correspond.
            this.EnforceBIP30 = this.EnforceBIP30 && ((bip34HeightChainedBlock == null) || !(bip34HeightChainedBlock.HashBlock == chainparams.BIP34Hash));

            // BIP16 didn't become active until Apr 1 2012.
            var  nBIP16SwitchTime       = Utils.UnixTimeToDateTime(1333238400);
            bool fStrictPayToScriptHash = (nextBlock.Header.BlockTime >= nBIP16SwitchTime);

            this.ScriptFlags = fStrictPayToScriptHash ? ScriptVerify.P2SH : ScriptVerify.None;

            // Start enforcing the DERSIG (BIP66) rule.
            if (nextBlock.Height >= chainparams.BuriedDeployments[BuriedDeployments.BIP66])
            {
                this.ScriptFlags |= ScriptVerify.DerSig;
            }

            // Start enforcing CHECKLOCKTIMEVERIFY, (BIP65) for block.nVersion=4
            // blocks, when 75% of the network has upgraded.
            if (nextBlock.Height >= chainparams.BuriedDeployments[BuriedDeployments.BIP65])
            {
                this.ScriptFlags |= ScriptVerify.CheckLockTimeVerify;
            }

            // Start enforcing BIP68 (sequence locks), BIP112 (CHECKSEQUENCEVERIFY) and BIP113 (Median Time Past) using versionbits logic.
            if (prevBlockStates[(int)BIP9Deployments.CSV] == ThresholdState.Active)
            {
                this.ScriptFlags   |= ScriptVerify.CheckSequenceVerify;
                this.LockTimeFlags |= Transaction.LockTimeFlags.VerifySequence;
                this.LockTimeFlags |= Transaction.LockTimeFlags.MedianTimePast;
            }

            // Start enforcing WITNESS rules using versionbits logic.
            if (prevBlockStates[(int)BIP9Deployments.Segwit] == ThresholdState.Active)
            {
                this.ScriptFlags |= ScriptVerify.Witness;
            }

            // Enforce block.nVersion=2 rule that the coinbase starts with serialized block height
            if (nextBlock.Height >= chainparams.BuriedDeployments[BuriedDeployments.BIP34])
            {
                this.EnforceBIP34 = true;
            }
        }
コード例 #36
0
ファイル: Script.cs プロジェクト: woutersmit/NBitcoin
		public static bool VerifyScript(Script scriptPubKey, Transaction tx, int i, ScriptVerify scriptVerify = ScriptVerify.Standard, SigHash sigHash = SigHash.Undefined)
		{
			ScriptError unused;
			var scriptSig = tx.Inputs[i].ScriptSig;
			return VerifyScript(scriptSig, scriptPubKey, tx, i, scriptVerify, sigHash, out unused);
		}
コード例 #37
0
        /// <summary>
        /// Validates transaction inputs against transaction data for a specific set of script verify flags.
        /// Check whether all inputs of this transaction are valid (no double spends, scripts & signatures, amounts)
        /// This does not modify the UTXO set.
        /// </summary>
        /// <seealso>https://github.com/bitcoin/bitcoin/blob/febf3a856bcfb8fef2cb4ddcb8d1e0cab8a22580/src/validation.cpp#L1259</seealso>
        /// <param name="ruleContext">Current mempool rule context.</param>
        /// <param name="context">Current validation context.</param>
        /// <param name="scriptVerify">Script verify flag.</param>
        /// <param name="txData">Transaction data.</param>
        /// <returns>Whether inputs are valid.</returns>
        private bool CheckInputs(MempoolValidationContext context, ScriptVerify scriptVerify, PrecomputedTransactionData txData)
        {
            Transaction tx = context.Transaction;

            if (tx.IsCoinBase)
            {
                return(true);
            }

            // TODO: The original code does not appear to do these checks here. Reevaluate if this needs to be done, or perhaps moved to another rule/method.
            this.consensusRuleEngine.GetRule <CheckUtxosetRule>().CheckInputs(context.Transaction, context.View.Set, this.chainIndexer.Height + 1);

            // TODO: Original code has the concept of a script execution cache. This might be worth looking into for performance improvements. Signature checks are expensive.

            for (int iInput = 0; iInput < tx.Inputs.Count; iInput++)
            {
                TxIn  input   = tx.Inputs[iInput];
                int   iiInput = iInput;
                TxOut txout   = context.View.GetOutputFor(input);

                var checker = new TransactionChecker(tx, iiInput, txout.Value, txData);
                var ctx     = new ScriptEvaluationContext(this.network)
                {
                    ScriptVerify = scriptVerify
                };
                if (!ctx.VerifyScript(input.ScriptSig, txout.ScriptPubKey, checker))
                {
                    if ((scriptVerify & ScriptVerify.StandardNotMandatory) == ScriptVerify.StandardNotMandatory)
                    {
                        // Check whether the failure was caused by a non-mandatory script verification check, such as
                        // non-standard DER encodings or non-null dummy arguments; if so, don't trigger DoS protection to
                        // avoid splitting the network between upgraded and non-upgraded nodes.

                        // TODO: Investigate whether the checker and context can be reused instead of recreated. Probably not.
                        checker = new TransactionChecker(tx, iiInput, txout.Value, txData);
                        ctx     = new ScriptEvaluationContext(this.network)
                        {
                            ScriptVerify = (scriptVerify & ~ScriptVerify.StandardNotMandatory)
                        };

                        if (ctx.VerifyScript(input.ScriptSig, txout.ScriptPubKey, checker))
                        {
                            this.logger.LogTrace("(-)[FAIL_NON_MANDATORY_SCRIPT_VERIFY]");
                            // TODO: Check what this actually means in Core's logic. If it is on testnet/regtest and RequireStandard is false, is the transaction still rejected?
                            context.State.Fail(MempoolErrors.NonMandatoryScriptVerifyFlagFailed, ctx.Error.ToString()).Throw();
                        }
                    }

                    // Failures of other flags indicate a transaction that is invalid in new blocks, e.g. an invalid P2SH. We DoS ban
                    // such nodes as they are not following the protocol. That said, during an upgrade careful thought should be taken
                    // as to the correct behavior - we may want to continue peering with non-upgraded nodes even after soft-fork
                    // super-majority signaling has occurred.

                    // Further comment from Bitcoin Core:
                    // MANDATORY flag failures correspond to
                    // ValidationInvalidReason::CONSENSUS. Because CONSENSUS
                    // failures are the most serious case of validation
                    // failures, we may need to consider using
                    // RECENT_CONSENSUS_CHANGE for any script failure that
                    // could be due to non-upgraded nodes which we may want to
                    // support, to avoid splitting the network (but this
                    // depends on the details of how net_processing handles
                    // such errors).

                    this.logger.LogTrace("(-)[FAIL_MANDATORY_SCRIPT_VERIFY]");
                    context.State.Fail(MempoolErrors.MandatoryScriptVerifyFlagFailed, ctx.Error.ToString()).Throw();
                }
            }

            return(true);
        }
コード例 #38
0
ファイル: Script.cs プロジェクト: woutersmit/NBitcoin
		public static bool VerifyScript(Script scriptSig, Script scriptPubKey, Transaction tx, int i, ScriptVerify scriptVerify, SigHash sigHash, out ScriptError error)
		{
			var eval = new ScriptEvaluationContext
			{
				SigHash = sigHash,
				ScriptVerify = scriptVerify
			};
			var result = eval.VerifyScript(scriptSig, scriptPubKey, tx, i);
			error = eval.Error;
			return result;
		}
コード例 #39
0
        /// <summary>
        /// Check if valid transaction signature
        /// </summary>
        /// <param name="sig">Signature in bytes</param>
        /// <param name="scriptVerify">Verification rules</param>
        /// <returns>True if valid</returns>
        public static bool IsValid(byte[] sig, ScriptVerify scriptVerify = ScriptVerify.DerSig | ScriptVerify.StrictEnc)
        {
            ScriptError error;

            return(IsValid(sig, scriptVerify, out error));
        }
コード例 #40
0
ファイル: Script.cs プロジェクト: woutersmit/NBitcoin
		public static bool VerifyScriptConsensus(Script scriptPubKey, Transaction tx, uint nIn, ScriptVerify flags)
		{
			var scriptPubKeyBytes = scriptPubKey.ToBytes();
			var txToBytes = tx.ToBytes();

			var err = BitcoinConsensusError.ERR_OK;
			var valid = VerifyScriptConsensus(scriptPubKeyBytes, (uint)scriptPubKeyBytes.Length, txToBytes, (uint)txToBytes.Length, nIn, flags, ref err);
			return valid == 1;
		}
コード例 #41
0
        // Check whether all inputs of this transaction are valid (no double spends, scripts & sigs, amounts)
        // This does not modify the UTXO set. If pvChecks is not NULL, script checks are pushed onto it
        // instead of being performed inline.
        private bool CheckInputs(MempoolValidationContext context, ScriptVerify scriptVerify,
                                 PrecomputedTransactionData txData)
        {
            var tx = context.Transaction;

            if (!context.Transaction.IsCoinBase)
            {
                this.consensusValidator.CheckInputs(context.Transaction, context.View.Set, this.chain.Height + 1);

                for (int iInput = 0; iInput < tx.Inputs.Count; iInput++)
                {
                    var input    = tx.Inputs[iInput];
                    int iiIntput = iInput;
                    var txout    = context.View.GetOutputFor(input);

                    if (this.consensusValidator.UseConsensusLib)
                    {
                        Script.BitcoinConsensusError error;
                        return(Script.VerifyScriptConsensus(txout.ScriptPubKey, tx, (uint)iiIntput, scriptVerify, out error));
                    }
                    else
                    {
                        var checker = new TransactionChecker(tx, iiIntput, txout.Value, txData);
                        var ctx     = new ScriptEvaluationContext();
                        ctx.ScriptVerify = scriptVerify;
                        if (ctx.VerifyScript(input.ScriptSig, txout.ScriptPubKey, checker))
                        {
                            return(true);
                        }
                        else
                        {
                            //TODO:

                            //if (flags & STANDARD_NOT_MANDATORY_VERIFY_FLAGS)
                            //{
                            //	// Check whether the failure was caused by a
                            //	// non-mandatory script verification check, such as
                            //	// non-standard DER encodings or non-null dummy
                            //	// arguments; if so, don't trigger DoS protection to
                            //	// avoid splitting the network between upgraded and
                            //	// non-upgraded nodes.
                            //	CScriptCheck check2(*coins, tx, i,
                            //			flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, cacheStore, &txdata);
                            //	if (check2())
                            //		return state.Invalid(false, REJECT_NONSTANDARD, strprintf("non-mandatory-script-verify-flag (%s)", ScriptErrorString(check.GetScriptError())));
                            //}
                            //// Failures of other flags indicate a transaction that is
                            //// invalid in new blocks, e.g. a invalid P2SH. We DoS ban
                            //// such nodes as they are not following the protocol. That
                            //// said during an upgrade careful thought should be taken
                            //// as to the correct behavior - we may want to continue
                            //// peering with non-upgraded nodes even after soft-fork
                            //// super-majority signaling has occurred.
                            context.State.Fail(MempoolErrors.MandatoryScriptVerifyFlagFailed, ctx.Error.ToString()).Throw();
                        }
                    }
                }
            }

            return(true);
        }