src/main.cpp
//
// Check transaction inputs, and make sure any
// pay-to-script-hash transactions are evaluating IsStandard scripts
//
// Why bother? To avoid denial-of-service attacks; an attacker
// can submit a standard HASH... OP_EQUAL transaction,
// which will get accepted into blocks. The redemption
// script can be anything; an attacker could use a very
// expensive-to-check-upon-redemption script like:
//   DUP CHECKSIG DROP ... repeated 100 times... OP_1
//
Check transaction inputs, and make sure any
pay-to-script-hash transactions are evaluating IsStandard scripts


Check transaction inputs and make sure any pay - to - script - hash transactions are evaluating IsStandard scripts
bool CTransaction::AreInputsStandard(const MapPrevTx& mapInputs) const
{
    if (IsCoinBase())
        return true; 
    for (unsigned int i = 0; i < vin.size(); i++)
    {
        const CTxOut& prev = GetOutputFor(vin[i], mapInputs);
        vector<vector<unsigned char> > vSolutions;
        txnouttype whichType;
        const CScript& prevScript = prev.scriptPubKey;
        if (!Solver(prevScript, whichType, vSolutions))
            return false;
        int nArgsExpected = ScriptSigArgsExpected(whichType, vSolutions);
        if (nArgsExpected < 0)
            return false;
        vector<vector<unsigned char> > stack;
        if (!EvalScript(stack, vin[i].scriptSig, *this, i, false, 0))
            return false;
        if (whichType == TX_SCRIPTHASH)
        {
            if (stack.empty())
                return false;
            CScript subscript(stack.back().begin(), stack.back().end());
            vector<vector<unsigned char> > vSolutions2;
            txnouttype whichType2;
            if (!Solver(subscript, whichType2, vSolutions2))
                return false;
            if (whichType2 == TX_SCRIPTHASH)
                return false;
            int tmpExpected;
            tmpExpected = ScriptSigArgsExpected(whichType2, vSolutions2);
            if (tmpExpected < 0)
                return false;
            nArgsExpected += tmpExpected;
        }
        if (stack.size() != (unsigned int)nArgsExpected)
            return false;
    }
    return true;
}
bool CTransaction :: AreInputsStandard ( const MapPrevTx & mapInputs ) const { if ( IsCoinBase ( ) ) return true ; for ( unsigned int i = 0 ; i < vin . size ( ) ; i ++ ) { const CTxOut & prev = GetOutputFor ( vin [ i ] , mapInputs ) ; vector < vector < unsigned char > > vSolutions ; txnouttype whichType ; const CScript & prevScript = prev . scriptPubKey ; if ( ! Solver ( prevScript , whichType , vSolutions ) ) return false ; int nArgsExpected = ScriptSigArgsExpected ( whichType , vSolutions ) ; if ( nArgsExpected < 0 ) return false ; vector < vector < unsigned char > > stack ; if ( ! EvalScript ( stack , vin [ i ] . scriptSig , * this , i , false , 0 ) ) return false ; if ( whichType == TX_SCRIPTHASH ) { if ( stack . empty ( ) ) return false ; CScript subscript ( stack . back ( ) . begin ( ) , stack . back ( ) . end ( ) ) ; vector < vector < unsigned char > > vSolutions2 ; txnouttype whichType2 ; if ( ! Solver ( subscript , whichType2 , vSolutions2 ) ) return false ; if ( whichType2 == TX_SCRIPTHASH ) return false ; int tmpExpected ; tmpExpected = ScriptSigArgsExpected ( whichType2 , vSolutions2 ) ; if ( tmpExpected < 0 ) return false ; nArgsExpected += tmpExpected ; } if ( stack . size ( ) != ( unsigned int ) nArgsExpected ) return false ; } return true ; }
Check transaction inputs, and make sure any
pay-to-script-hash transactions are evaluating IsStandard scripts
Check transaction inputs and make sure any pay - to - script - hash transactions are evaluating IsStandard scripts
// Coinbases don't use vin normally // get the scriptPubKey corresponding to this input: // Transactions with extra stuff in their scriptSigs are // non-standard. Note that this EvalScript() call will // be quick, because if there are any operations // beside "push data" in the scriptSig the // IsStandard() call returns false