TeachMeBitcoin

What is the Script Interpreter

From TeachMeBitcoin, the free encyclopedia Reading time: 3 min

What is the Script Interpreter?

The Script interpreter is the component of Bitcoin Core (and every other node implementation) that executes Bitcoin Script programs. It is the software that takes raw script bytes, runs them step by step, and returns a pass or fail result.

Location in Bitcoin Core

In Bitcoin Core, the script interpreter lives primarily in:

src/script/interpreter.cpp
src/script/interpreter.h

The main entry point is the VerifyScript() function, which orchestrates the full validation of an input:

// From Bitcoin Core src/script/interpreter.cpp (simplified):
bool VerifyScript(
    const CScript& scriptSig,
    const CScript& scriptPubKey,
    const CScriptWitness* witness,
    unsigned int flags,
    const BaseSignatureChecker& checker,
    ScriptError* serror
)

The EvalScript Function

The core execution engine is EvalScript(), which processes one script at a time:

bool EvalScript(
    std::vector<std::vector<unsigned char>>& stack,
    const CScript& script,
    unsigned int flags,
    const BaseSignatureChecker& checker,
    SigVersion sigversion,
    ScriptError* serror
)

This function iterates over every opcode in the script, maintains the main stack and alt stack, and applies each operation in sequence.

Interpreter Flags

The interpreter accepts a set of flags that control which validation rules are enforced. These flags allow Bitcoin to deploy soft fork upgrades without breaking backward compatibility:

// Key script verification flags (from script/script_flags.h):
SCRIPT_VERIFY_P2SH          // Enable P2SH validation (BIP 16)
SCRIPT_VERIFY_STRICTENC     // Enforce DER signature encoding
SCRIPT_VERIFY_LOW_S         // Require low-S signatures (BIP 62)
SCRIPT_VERIFY_NULLDUMMY     // Require OP_0 for CHECKMULTISIG bug
SCRIPT_VERIFY_WITNESS       // Enable SegWit validation (BIP 141)
SCRIPT_VERIFY_TAPROOT       // Enable Taproot validation (BIP 341)
SCRIPT_VERIFY_CLEANSTACK    // Require exactly one item left on stack

The Signature Checker

The interpreter does not directly verify cryptographic signatures itself. Instead, it calls a BaseSignatureChecker interface. This abstraction allows the same interpreter to be used in different contexts — full validation, script simulation, and testing.

class BaseSignatureChecker {
public:
    virtual bool CheckSig(
        std::vector<unsigned char>& sig,
        std::vector<unsigned char>& pubKey,
        const CScript& scriptCode,
        SigVersion sigversion
    ) const { return false; }

    virtual bool CheckLockTime(const CScriptNum& nLockTime) const { return false; }
    virtual bool CheckSequence(const CScriptNum& nSequence) const { return false; }
};

Error Codes

When a script fails, the interpreter returns a specific error code:

enum ScriptError {
    SCRIPT_ERR_OK = 0,
    SCRIPT_ERR_EVAL_FALSE,          // Stack top was false
    SCRIPT_ERR_OP_RETURN,           // Hit OP_RETURN
    SCRIPT_ERR_SCRIPT_SIZE,         // Script exceeded size limit
    SCRIPT_ERR_PUSH_SIZE,           // Push data exceeded 520 bytes
    SCRIPT_ERR_OP_COUNT,            // Too many opcodes
    SCRIPT_ERR_STACK_SIZE,          // Stack exceeded 1000 items
    SCRIPT_ERR_SIG_DER,             // Invalid DER signature
    SCRIPT_ERR_CHECKSIGVERIFY,      // CHECKSIGVERIFY failed
    SCRIPT_ERR_CHECKMULTISIGVERIFY, // CHECKMULTISIGVERIFY failed
    // ... many more
};
☕ Help support TeachMeBitcoin

TeachMeBitcoin is an ad-free, open-source educational repository curated by a passionate team of Bitcoin researchers and educators for public benefit. If you found our articles helpful, please consider supporting our hosting and ongoing content updates with a clean donation:

Ethereum: 0x578417C51783663D8A6A811B3544E1f779D39A85
Bitcoin: bc1q77k9e95rn669kpzyjr8ke9w95zhk7pa5s63qzz
Solana: 4ycT2ayqeMucixj3wS8Ay8Tq9NRDYRPKYbj3UGESyQ4J
Address copied to clipboard!