1

what is the criteria for a txout script to be accepted into a mined block? is there any criteria at all? the reason i ask is that OP_RETURN is regularly used in txout scripts yet it is not spendable:

case OP_RETURN:
{
    return set_error(serror, SCRIPT_ERR_OP_RETURN);
}

and i have also seen transactions which push elements to the stack which are more than MAX_SCRIPT_ELEMENT_SIZE bytes.

i'm guessing that a syntactically incorrect script such as:

05aa
(ie OP_PUSHDATA(5) <aa>)

would not be permitted?

could someone point me to the code which miners use to validate whether a tx will be included or discarded as invalid (due to its txout scripts). i'm guessing it lies in main.cpp, but i would like to know where exactly, thanks.

obviously anybody can mine a block that is set up any way they like, but presumably there are fixed rules for whether it is considered valid or not - so other miners will know whether to use its hash as their prev-header-hash when mining the next block?

2 Answers 2

3

Absolutely no consensus validity checks are done on a scriptPubKey. Nodes have soft requirements called IsStandard for what they will relay to their peers as a transaction (a completely junk script or very large OP_RETURN output for example will not pass) but these are not consensus rules. Some miners will mine non-standard transactions into their blocks, but generally to get a transaction to them a transport other than the P2P network needs to be used.

OP_RETURN is a special case refereed to as "provably un-spendable", this is a response to people jamming hashes and other data into PubKeyHash outputs as a way of pegging them in time to the block chain. Due to there being no way of knowing if the output is actually valid or not these outputs must be stored forever in the UTXO pool. An OP_RETURN prefixed output can absolutely never be spent, so nodes can safely forget that they ever existed.

8
  • thanks for the reply! but surely if someone builds a block with a syntactically incorrect txout script then no other miners will build on top of it? i'm looking for that criteria - ie for building on top of an already mined block Commented Jun 16, 2015 at 11:05
  • i have added a last paragraph to the op explaining a bit better... Commented Jun 16, 2015 at 11:08
  • The output script is never verified in Bitcoin, you can make something that is complete junk (OP_CAT OP_CAT OP_CAT) and that is valid in a block. If there is no way to satisfy the script and spend it again, then the value of the BTC there is simply stuck there forever. This transaction output is similar to your example, it pushes junk onto the stack for no reason. webbtc.com/tx/… Bonus points if you can work out what it is pushing onto the stack.
    – Claris
    Commented Jun 16, 2015 at 11:11
  • hmm interesting. i'm guessing it is still syntactically correct though? eg 05aa would fail? if not then it might be possible to use txout scripts for buffer overflow attacks on users... Commented Jun 16, 2015 at 11:16
  • i know they cant be used in EvalScript() - that's not my question. Commented Jun 16, 2015 at 11:23
2

transaction ebc9fa1196a59e192352d76c0f6e73167046b9d37b8302b6bb6968dfd279b767 from the live blockchain contains a lot of syntactically incorrect txout scripts and is useful as a demonstration:

using pybitcointools:

#!/usr/bin/env python2.7                                                        

from bitcoin import *
tx_hex = fetchtx("ebc9fa1196a59e192352d76c0f6e73167046b9d37b8302b6bb6968dfd279b767")
tx_dict = deserialize(tx_hex)
for (txout_num, txout) in enumerate(tx_dict["outs"]):
    script = txout["script"]
    print "raw txout %d script: %s" % (txout_num, script)

output:

raw txout 0 script: 01
raw txout 1 script: 0201
raw txout 2 script: 4c
raw txout 3 script: 4c0201
raw txout 4 script: 4d
raw txout 5 script: 4dffff01
raw txout 6 script: 4e
raw txout 7 script: 4effffffff01

analysing each of these txout scripts:

01 = OP_PUSHDATA0(1)

this fails because it claims it will push 1 byte onto the stack, but then provides no bytes to push onto the stack

0201 = OP_PUSHDATA0(2) <01>

this fails because it claims it will push 2 bytes onto the stack, but then only provides 1 byte to push onto the stack

4c = OP_PUSHDATA1(?)

this fails because it is an incomplete OP_PUSHDATA1 opcode. the 4c byte should be followed by another byte specifying the number of data bytes to push onto the stack, however it is not.

4c0201 = OP_PUSHDATA1(2) <01>

this fails because it claims it will push 2 bytes onto the stack, but then only provides 1 byte to push onto the stack.

etc

its funny that the output scripts in this particular transaction each have a different syntactically incorrect use of the OP_PUSHDATA commands. its almost as if someone had the same question as this and wanted to test if any syntax checking was implemented on scriptpubkeys. i'm glad they did this because its a very conclusive way to demonstrate that absolutely no syntax checking (and therefore no other checks either) are performed on scriptpubkeys before they are spent.

7
  • You'll find a lot of scripts like this on testnet3, and a smaller number on the main network. Many of them are attempting (and actually manage in some cases) to break reimplementations using obscure and undocumented behaviors.
    – Claris
    Commented Jun 18, 2015 at 6:52
  • yep! it broke my re-implementation - that's the reason i'm asking :) but i don't see a whole lot of value for validating testnet blocks - people can put anything in there and there is not much hashpower to even guarantee valid blocks. Commented Jun 18, 2015 at 8:22
  • 1
    You're never going to download a block with invalid contents, because the block would just simply be invalid. The amount of proof of work for this is almost entirely orthogonal. You really shouldn't be reimplementing script, history has shown (bitcoinjs, bitcoin-ruby, btcd) that nobody has the capability to clone the behavior directly, no matter how many millions of dollars are poured into the effort. Unless this is for fun or experience, link to libconsensus and avoid losing piles of money. It's not foolproof, but it means you won't have avoidable mistakes in script execution.
    – Claris
    Commented Jun 18, 2015 at 8:43
  • 1
    thanks for the warning but for me its purely educational. you never really know something until you can build it yourself from scratch. Commented Jun 18, 2015 at 12:09
  • i didn't know about libconsensus - that looks really useful! Commented Jun 18, 2015 at 12:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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