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); }
/// <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; }
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; } }
public bool Check(PubKey pubKey, Script scriptPubKey, IndexedTxIn txIn, ScriptVerify verify = ScriptVerify.Standard) { return Check(pubKey, scriptPubKey, txIn.Transaction, txIn.Index, verify); }
private static extern int VerifyScriptConsensusWithAmount(byte[] scriptPubKey, uint scriptPubKeyLen, long amount, byte[] txTo, uint txToLen, uint nIn, ScriptVerify flags, ref BitcoinConsensusError err);
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)); }
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)); }
private static extern int VerifyScriptConsensus(byte[] scriptPubKey, uint scriptPubKeyLen, byte[] txTo, uint txToLen, uint nIn, ScriptVerify flags, ref BitcoinConsensusError err);
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 }
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)); }
/// <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); }
/// <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); }
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); }
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)); }
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); }
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); }
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)); }
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); }
/// <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); }
public bool Check(PubKey pubKey, Script scriptPubKey, IndexedTxIn txIn, ScriptVerify verify = ScriptVerify.Standard) { return(Check(pubKey, scriptPubKey, txIn.Transaction, txIn.Index, verify)); }
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)); }
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)); }
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); }
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); }
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 }
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 }
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 }
/// <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); }
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)); }
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; }
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); }
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)); } }
/// <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); }
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 }
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; } }
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); }
/// <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); }
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; }
/// <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)); }
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; }
// 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); }