user-1: Reading through the wiki (bitcoin.it consensus versions) I noticed that release 0.3.7 ("scriptSig + scriptPubKey evaluations separated") is listed as a hard-forking change. In BitMEX's account of consensus forks, the same version is described as "potentially a non-deterministic hardfork". I would like to understand the rationale for this description.
In previous versions to 0.3.7, the scriptSig was concatenated to the scriptPubKey, and also allowed executable opcodes (such as OP_RETURN, at the time when it finished the script's execution without failing, allowing for the OP_1 OP_RETURN bug). The commit with the changes can be found here.
I guess disabling OP_RETURN can be considered a soft-fork, because previously valid transactions are now invalid. But I cannot come up with any example of a transaction, previously invalid, that would become valid after separating the evaluation of the scriptSig and scriptPubKey. The best I have come up with (with the old meaning of OP_RETURN in mind) is:
scriptSig: OP_2 (push the next 2 bytes to the stack)
scriptPubKey: OP_1 OP_RETURN OP_FALSE

Evaluated together, OP_1 OP_RETURN would be pushed to the stack as data instead of evaluated, therefore failing the script after OP_FALSE. However, when evaluated separately, the scriptPubKey would pass as valid (... but not the scriptSig, for providing no data to push?).
Thank you

user942: I haven't tested it, but perhaps scripts using the alt stack (which IIRC is cleared with the split execution)?

user101498: Yes. An invalid pair of arguments to CHECKSIG can become valid after the fork. This is because the scriptSig is evaluated too.
scriptPubKey: OP_TRUE
scriptSig: <sig> <pubkey> OP_CHECKSIGVERIFY

Before the fork, sig would be checked with a scriptCode containing the concatenation of the scriptSig, a CODESEPARATOR, and the scriptPubKey.
After the fork, sig would be checked with a scriptCode containing only the scriptSig itself.
Therefore the hashes differ and a signature could be valid after the fork whereas it was invalid before.

-1: <p>Reading through the wiki <a href="https://en.bitcoin.it/wiki/Consensus_versions" rel="nofollow noreferrer">(bitcoin.it consensus versions)</a> I noticed that release 0.3.7 (&quot;<code>scriptSig</code> + <code>scriptPubKey</code> evaluations separated&quot;) is listed as a hard-forking change. In BitMEX's <a href="https://blog.bitmex.com/bitcoins-consensus-forks/" rel="nofollow noreferrer">account of consensus forks</a>, the same version is described as &quot;potentially a non-deterministic hardfork&quot;. I would like to understand the rationale for this description.</p>
<p>In previous versions to 0.3.7, the <code>scriptSig</code> was concatenated to the <code>scriptPubKey</code>, and also allowed executable opcodes (such as <code>OP_RETURN</code>, at the time when it finished the script's execution without failing, allowing for the <code>OP_1 OP_RETURN</code> bug). The commit with the changes can be found <a href="https://github.com/bitcoin/bitcoin/commit/73aa262647ff9948eaf95e83236ec323347e95d0" rel="nofollow noreferrer">here</a>.</p>
<p>I guess disabling <code>OP_RETURN</code> can be considered a soft-fork, because previously valid transactions are now invalid. But I cannot come up with any example of a transaction, previously invalid, that would become valid after separating the evaluation of the <code>scriptSig</code> and <code>scriptPubKey</code>. The best I have come up with (with the old meaning of <code>OP_RETURN</code> in mind) is:</p>
<pre><code>scriptSig: OP_2 (push the next 2 bytes to the stack)
scriptPubKey: OP_1 OP_RETURN OP_FALSE
</code></pre>
<p>Evaluated together, <code>OP_1 OP_RETURN</code> would be pushed to the stack as data instead of evaluated, therefore failing the script after <code>OP_FALSE</code>. However, when evaluated separately, the <code>scriptPubKey</code> would pass as valid (... but not the <code>scriptSig</code>, for providing no data to push?).</p>
<p>Thank you</p>
 942: <p>I haven't tested it, but perhaps scripts using the alt stack (which IIRC is cleared with the split execution)?</p>
 101498: <p>Yes. An invalid pair of arguments to <code>CHECKSIG</code> can become valid after the fork. This is because the <code>scriptSig</code> is evaluated too.</p>
<pre><code>scriptPubKey: OP_TRUE
scriptSig: &lt;sig&gt; &lt;pubkey&gt; OP_CHECKSIGVERIFY
</code></pre>
<p>Before the fork, <code>sig</code> <a href="https://github.com/bitcoin/bitcoin/commit/73aa262647ff9948eaf95e83236ec323347e95d0#diff-27496895958ca30c47bbb873299a2ad7a7ea1003a9faa96b317250e3b7aa1fefL1153" rel="nofollow noreferrer">would be checked</a> with a <code>scriptCode</code> containing the concatenation of the <code>scriptSig</code>, a <code>CODESEPARATOR</code>, and the <code>scriptPubKey</code>.<br />
After the fork, <code>sig</code> <a href="https://github.com/bitcoin/bitcoin/commit/73aa262647ff9948eaf95e83236ec323347e95d0#diff-27496895958ca30c47bbb873299a2ad7a7ea1003a9faa96b317250e3b7aa1fefR1117-R1120" rel="nofollow noreferrer">would be checked</a> with a <code>scriptCode</code> containing only the <code>scriptSig</code> itself.</p>
<p>Therefore the hashes differ and a signature could be valid after the fork whereas it was invalid before.</p>
