Bitcoin Forum

Bitcoin => Development & Technical Discussion => Topic started by: qrius1111 on June 15, 2015, 01:29:17 PM



Title: OP_PUSHDATA lies
Post by: qrius1111 on June 15, 2015, 01:29:17 PM
i have found a transaction in the live blockchain (http://blockexplorer.com/tx/77822fd6663c665104119cb7635352756dfc50da76a92d417ec1a12c518fad69) which claims to push 0xffffffff bytes onto the stack, but infact only pushes 1443 bytes. the relevant txout script is:

OP_IF OP_INVALIDOPCODE 4effffffff 46726f6d20...2e340a0a OP_ENDIF

could someone explain how fewer than 0xffffffff bytes are pushed here? i actually don't even understand how the parser can identify the OP_ENDIF at all - it should see that as part of the 0xfffffff bytes i would have thought.

links to the satoshi source code are welcome but i don't understand much c++ so i might need a walkthrough.


Title: Re: OP_PUSHDATA lies
Post by: amaclin on June 15, 2015, 01:36:41 PM
There are two push operations there.
First operation pushes 5 bytes ( 4e ff ff ff ff )
Second operation pushes 1443 bytes via opcode OP_PUSHDATA2

OP_IF OP_INVALIDOPCODE <data5> OP_PUSHDATA2 <data1443> OP_ENDIF
see also: https://bitcointalk.org/index.php?topic=640453.0


Title: Re: OP_PUSHDATA lies
Post by: qrius1111 on June 16, 2015, 12:57:41 AM
you're right, my bad. its been a while since i looked at the raw bytes for this script - i was investigating the mysterious contents ;) i got confused and thought that the output on blockexplorer.com was complete (forgetting they don't show the pushdata's)

for my own satisfaction and for anybody else reading this: the start of the script in hex is:

63ff054effffffff4da30546726f6d...

decoding:

0x63 = OP_IF
0xff = OP_INVALIDOPCODE
0x05 = OP_PUSHDATA0 (5 bytes)
push <4effffffff> onto the stack
0x4d = OP_PUSHDATA2 (use the next 2 bytes little endian to determine how many bytes to push onto the stack)
0xa305 = push 0x05a3 (=1443) bytes onto the stack
push <46726f6d...> onto the stack


Title: Re: OP_PUSHDATA lies
Post by: qrius1111 on June 16, 2015, 01:42:36 AM
one more thing - doesn't this 1443 byte stack element violate the MAX_SCRIPT_ELEMENT_SIZE criteria? shouldn't this mean that the script would fail and so should not be included in the blockchain?


Title: Re: OP_PUSHDATA lies
Post by: jl2012 on June 16, 2015, 03:46:14 AM
one more thing - doesn't this 1443 byte stack element violate the MAX_SCRIPT_ELEMENT_SIZE criteria? shouldn't this mean that the script would fail and so should not be included in the blockchain?

validity of scriptPubKey is not verified until someone tries to spent it


Title: Re: OP_PUSHDATA lies
Post by: amaclin on June 16, 2015, 06:03:44 AM
0x4d = OP_PUSHDATA1 (use the next 2 bytes little endian to determine how many bytes to push onto the stack)
Let us call this opcode OP_PUSHDATA2  ;D


Title: Re: OP_PUSHDATA lies
Post by: qrius1111 on June 17, 2015, 01:00:15 AM
0x4d = OP_PUSHDATA1 (use the next 2 bytes little endian to determine how many bytes to push onto the stack)
Let us call this opcode OP_PUSHDATA2  ;D

right you are (again). updated...


Title: Re: OP_PUSHDATA lies
Post by: qrius1111 on June 17, 2015, 01:04:19 AM
one more thing - doesn't this 1443 byte stack element violate the MAX_SCRIPT_ELEMENT_SIZE criteria? shouldn't this mean that the script would fail and so should not be included in the blockchain?

validity of scriptPubKey is not verified until someone tries to spent it

that explains a lot! are there any checks at all though? for example what if i literally did OP_PUSHDATA0(10 bytes) <abab> - ie only providing 2 bytes to push, even though i claim to be pushing 10 bytes. would that still make its way into the live blockchain?


Title: Re: OP_PUSHDATA lies
Post by: amaclin on June 17, 2015, 05:47:49 AM
one more thing - doesn't this 1443 byte stack element violate the MAX_SCRIPT_ELEMENT_SIZE criteria? shouldn't this mean that the script would fail and so should not be included in the blockchain?

validity of scriptPubKey is not verified until someone tries to spent it

that explains a lot! are there any checks at all though? for example what if i literally did OP_PUSHDATA0(10 bytes) <abab> - ie only providing 2 bytes to push, even though i claim to be pushing 10 bytes. would that still make its way into the live blockchain?
yes and no

yes: such output is valid
https://blockchain.info/tx/ebc9fa1196a59e192352d76c0f6e73167046b9d37b8302b6bb6968dfd279b767

no: it is very difficult (but still possible) to include such output into the blockchain today


Title: Re: OP_PUSHDATA lies
Post by: qrius1111 on June 17, 2015, 07:33:04 AM
exactly what i wanted to know! thanks a million :)


Title: Re: OP_PUSHDATA lies
Post by: amaclin on June 17, 2015, 08:03:37 AM
exactly what i wanted to know! thanks a million :)
FYI http://bitcoin.stackexchange.com/questions/29754/history-behind-the-scripting-language-in-bitcoin

Quote
...
This functional aspect of Script was especially important when scripts were still evaluated by directly concatenating the scriptSig and scriptPubKey instead of evaluating them separately as is done today.
...

bitcoin-0.1.3 (sources available here (http://www.bitcointrading.com/forum/bitcoin-clients/original-bitcoin-source-code-archives/) )
Code:
bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsigned int nIn, int nHashType)
{
    assert(nIn < txTo.vin.size());
    const CTxIn& txin = txTo.vin[nIn];
    if (txin.prevout.n >= txFrom.vout.size())
        return false;
    const CTxOut& txout = txFrom.vout[txin.prevout.n];

    if (txin.prevout.hash != txFrom.GetHash())
        return false;

    return EvalScript(txin.scriptSig + CScript(OP_CODESEPARATOR) + txout.scriptPubKey, txTo, nIn, nHashType);
}
This is very funny bug: concatenating scriptSig and scriptPubKey and executing the result data as one script :)