Is there any part of the Bitcoin protocol that established a limit on the maximum number of op_codes in a script.

Recently I have hit the limit for the bitcoin core client. In: https://github.com/bitcoin/bitcoin/blob/ce56f5621a94dcc2159ebe57e43da727eab18e6c/src/script/interpreter.cpp in line 276 you find:

   if (opcode > OP_16 && ++nOpCount > 201)
        return set_error(serror, SCRIPT_ERR_OP_COUNT);*

I interpret this line as saying that, outside standard type of transactions, there is a limit to 201 operations beside pushing a number from 0 to 16 to the stack.

Is this defined in any part of the protocol or discussed in any BIP?

I know there are limits for multiscript transactions: https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki#520byte_limitation_on_serialized_script_size and that the number of signatures should be limited to avoid certain attacks, but for lightweight operations (OP_ADD and the like) I cannot find any explanation on the limit and the exact 201 value.

P.S: I found the error when trying to spend the offending script. Curiously, I was allowed to send the transaction. It is when the client tries to verify the data for the next transaction when there is a problem.


Most if not all constants like that are not described, documented or otherwise discussed. For the most part the Bitcoin Core code is the reference which everything else follows, rather than the code trying to conform to any sort of standard. If it were hinged on a particular piece of documentation the network would need to be hard forked every time there was a new behavior found that didn't meet the specification.

201 operations is indeed the limit, and there is also a hard limit on the number of signature verifications that can occur in a block as well. Of all things in Bitcoin the script engine is probably the least well documented of all and has a number of oddities, partly due to its late inclusion.

It is when the client tries to verify the data for the next transaction when there is a problem.

You can make all sorts of completely invalid output scripts, because as you have found, there's no validity checks on them until they are spent. It is up to the author of non standard scripts to understand the system and not render their coins un-spendable. If you don't understand it, try these things out on testnet3 before you lose real money to them.

  • It's all testnet3 testing. In fact I managed to push the transaction to the mempool of a particular relay node: test.webbtc.com/mempool_tx/… They use a different Ruby implementation of Bitcoin. It seems, nevertheless, that most nodes use Bitcoin Core and the transaction will remain in a limbo for some time and then disappear. If it got relayed by Ruby clients, would the block be rejected by the network and create a fork or become part of the blockchain? Once in block is included there is less checking... Jun 24 '15 at 14:58
  • Your transaction is rejected by Bitcoin Core (-25), so Bitcoin Ruby accepting it would be erroneous. Your transaction is effectively nonsense and is trying to spend an OP_RETURN (unspendable) output so this isn't particularly surprising. Block validation is no less strict than transaction validation, in fact the validation is cached and reused in both.
    – Claris
    Jun 24 '15 at 17:38
  • @halftimepad re test.webbtc.com/mempool_tx .... What is that exactly? I knew of the relay or pushTx of the API, but I'm interested what you mean here. Are you pushing to this node via REST POST or BTC Core? Jun 25 '15 at 2:02
  • It's the output of webbtc.com/relay_tx .
    – Claris
    Jun 25 '15 at 2:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.