IsStandard() Rules in Bitcoin Core
IsStandard() Rules in Bitcoin Core
IsStandard() is a function in Bitcoin Core that determines whether a transaction meets the node's relay policy requirements. It is a multi-part check that examines transaction structure, script types, sizes, and other properties.
Location in Bitcoin Core
src/policy/policy.cpp → IsStandardTx(), IsStandard()
src/policy/policy.h → Declarations and constants
The Full IsStandardTx() Check
// Simplified version of IsStandardTx() in policy.cpp:
bool IsStandardTx(const CTransaction& tx, std::string& reason) {
// 1. Version check
if (tx.nVersion > MAX_STANDARD_VERSION || tx.nVersion < 1) {
reason = "version";
return false;
}
// 2. Transaction size limit (weight)
if (GetTransactionWeight(tx) > MAX_STANDARD_TX_WEIGHT) {
reason = "tx-size";
return false;
}
// 3. Check each input
for (const CTxIn& txin : tx.vin) {
// scriptSig size limit
if (txin.scriptSig.size() > MAX_SCRIPT_ELEMENT_SIZE) {
reason = "scriptsig-size";
return false;
}
// scriptSig must only use push opcodes
if (!txin.scriptSig.IsPushOnly()) {
reason = "scriptsig-not-pushonly";
return false;
}
}
// 4. Check each output
int nDataOut = 0;
for (const CTxOut& txout : tx.vout) {
TxoutType whichType;
if (!IsStandard(txout.scriptPubKey, whichType)) {
reason = "scriptpubkey";
return false;
}
if (whichType == TxoutType::NULL_DATA) {
nDataOut++;
}
// Dust check
if (IsDust(txout, dustRelayFee)) {
reason = "dust";
return false;
}
}
// Only one OP_RETURN output allowed
if (nDataOut > 1) {
reason = "multi-op-return";
return false;
}
return true;
}
Key Policy Constants
// From src/policy/policy.h:
static const unsigned int MAX_STANDARD_TX_WEIGHT = 400000;
static const unsigned int MAX_SCRIPT_ELEMENT_SIZE = 520;
static const unsigned int MAX_STANDARD_VERSION = 2;
static const unsigned int MAX_OP_RETURN_RELAY = 83; // OP_RETURN + 80 bytes data
static const CFeeRate DUST_RELAY_TX_FEE(3000); // 3000 sat/kB dust threshold
The scriptSig Push-Only Requirement
One of the most important standardness rules is that scriptSig must be push-only — it can only contain data push opcodes, not execution opcodes. This prevents a scriptSig from manipulating the execution environment before the locking script runs:
// STANDARD scriptSig (push-only):
<sig_bytes> <pubKey_bytes>
// NON-STANDARD scriptSig (contains OP_DUP):
OP_DUP <sig_bytes>
// Nodes would reject the second transaction from relay
The Dust Limit
An output is considered "dust" if the cost of spending it (in transaction fees) exceeds its value. Dust outputs are economically irrational — they cost more to spend than they're worth. Bitcoin Core refuses to relay transactions with dust outputs.
# Dust calculation (simplified):
def is_dust(output, dust_relay_fee):
# Estimate the input size needed to spend this output type
spend_size = estimate_input_size(output.scriptPubKey)
# Cost to spend = spend_size * dust_relay_fee / 1000
spend_cost = spend_size * dust_relay_fee / 1000
return output.value < spend_cost
# Typical dust thresholds:
# P2PKH: ~546 satoshis
# P2WPKH: ~294 satoshis
# P2TR: ~330 satoshis
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: