<p>Yes. Before P2SH, the most popular proposal for solving the problem that P2SH solves was OP_EVAL, which did just that: it repurposed OP_NOP1 as OP_EVAL.</p>

<p>A P2SH script looks like this:<br>
<code>[script input...] [serialized script] | OP_HASH160 [script hash] OP_EQUAL</code><br>
The equivalent OP_EVAL script would look like this to old nodes:<br>
<code>[script input] [serialized script] | OP_DUP OP_HASH160 [script hash] OP_EQUALVERIFY OP_NOP1</code><br>
Old nodes would only check that the serialized script matches the given script hash when hashed. The other stuff would be ignored.</p>

<p>New nodes would see:<br>
<code>[script input] [serialized script] | OP_DUP OP_HASH160 [script hash] OP_EQUALVERIFY OP_EVAL</code><br>
New nodes would understand OP_EVAL, so they'd check that the serialized script matches the given script <em>and</em> execute the serialized script. An OP_EVAL transaction might be seen as invalid for new nodes and valid for old nodes, but not the other way around. That's what makes it a softfork. If the majority of mining power is using the new rules, then this is not a hardfork because the longest chain will always converge to a state that is valid for both old and new nodes.</p>

<p>Depending on the new opcode's behavior, it may be necessary for new nodes to verify scripts twice to ensure that certain scripts can't cause hardforks. Scripts are verified once using the old script rules and once using the new rules.</p>

<p>The OP_EVAL proposal was eventually replaced with P2SH because it was discovered that OP_EVAL accidentally allowed Turing-complete scripts, which the Bitcoin developers didn't want. P2SH is very simple (and a bit weird) in part so that similar accidents would be easy to avoid. But there wasn't any technical problem with this method of adding a new opcode. Moreover, there's nothing restricting the behavior of new opcodes. For example, OP_EVAL could have interpreted its input in a different, Turing-complete language, though there are various reasons why this might not have been a good idea.</p>

CC BY-SA 3.0
2014-11-03T16:43:01.313Z
Thanks Theymos - does this mean that "pay to anyone" transactions are completely replaced by P2SH? Looking at this code blob...
https://github.com/bitcoin/bitcoin/blob/cd9114e5136ecc1f60baa43fffeeb632782f2353/src/script/script.cpp#L214-L221
pinhead
CC BY-SA 3.0
2014-11-03T21:00:07.503Z
@pinhead That code checks whether an output script meets the P2SH pattern and therefore requires additional verification. It seems unrelated to pay-to-anyone transactions. There are many ways of sending an output that anyone can redeem. The standard way is output=`OP_TRUE`, but any non-zero constant will work. There isn't much point in doing so, but you could use P2SH if you want: `OP_HASH160 [hash of OP_TRUE script] OP_EQUAL`.
theymos
CC BY-SA 3.0
2014-11-03T23:49:15.877Z
I guess what I meant was, is it still possible to use `OP_HASH160 [HASH OF SOMETHING] OP_EQUAL` as an output script if the `SOMETHING` is *not* a valid script (could be any data)
like,
https://en.bitcoin.it/wiki/Script#Transaction_puzzle
pinhead
CC BY-SA 3.0
2014-11-04T00:28:58.637Z
@pinhead No, but if you want to do that you can just add some junk at the start of the script to break the pattern, like `OP_0 OP_HASH160 [HASH OF SOMETHING] OP_EQUAL`.
theymos
CC BY-SA 3.0
2014-11-22T22:10:46.087Z
(I just noticed that the script I posted in my previous comment is actually unspendable. Change OP_0 to OP_NOP.)
theymos
CC BY-SA 3.0
2014-11-03T00:14:10.500Z
2014-11-03T03:32:48.887Z
2014-11-03T03:32:48.887Z
theymos
<p>The introduction P2SH didn't mean new OP codes nor repurposing old ones.</p>

<p>You cannot change any existing OP code with a soft fork by definition. The only thing you can do is to interpret information for new applications. For example, you can include the hash of a document to create a proof of existence scheme.</p>

CC BY-SA 3.0
2014-11-02T22:17:01.690Z
`The introduction P2SH didn't mean new OP codes nor repurposing old ones.` That's technically true (we didn't repurpose `OP_EQUAL`, we repurposed `OP_HASH160 <data> OP_EQUAL`) but it's awfully misleading.
Nick ODell
CC BY-SA 3.0
2014-11-02T22:48:41.647Z
Nick do you agree with Sortega that OP codes can't be repurposed without a hard fork? Say in the context of adding side chain support?
pinhead
CC BY-SA 3.0
2014-11-02T22:55:50.807Z
Turning a No-Op into OP_SPVVERIFY, etc
pinhead
CC BY-SA 3.0
2014-11-21T00:33:56.420Z
Maybe clarify the answer to point out that a [soft fork](https://bitcoin.org/en/developer-guide#consensus-rule-changes) requires upgraded nodes to comply with the same rules non-upgrade nodes follow, but that the upgraded nodes can also place additional limitations on how an op code is used.  For example, `op_hash160 <20 bytes> op_equal` retained their original meaning for non-upgraded nodes, but upgrade nodes only allowed spending a P2SH scriptPubKey if the spending scriptSig contained a redeemScript that didn't return false.
David A. Harding
CC BY-SA 3.0
2014-11-02T21:47:39.467Z
2014-11-02T21:47:39.467Z
sortega
<p>I understand that P2SH transaction types were added "softly" by repurposing a Tx message that is already valid, so old nodes won't reject them in blocks. </p>

<p>Is there a similar method to adding new script OP codes without a hard fork? In other words, how will old nodes interpret "No Op" commands after they have been repurposed for the upgraded protocol?</p>

<protocol><script><blockchain-fork>
Can new OP codes be added with a soft fork?
pinhead
# Can new OP codes be added with a soft fork?

(Asked by: username_0 on 2014-11-02)

I understand that P2SH transaction types were added "softly" by repurposing a Tx message that is already valid, so old nodes won't reject them in blocks.

Is there a similar method to adding new script OP codes without a hard fork? In other words, how will old nodes interpret "No Op" commands after they have been repurposed for the upgraded protocol?

**Tags:** protocol, script, blockchain-fork


---

## 2 answers

### Answer by username_1 on 2014-11-03. Score: 3 | Accepted answer

Yes. Before P2SH, the most popular proposal for solving the problem that P2SH solves was OP\_EVAL, which did just that: it repurposed OP\_NOP1 as OP\_EVAL.

A P2SH script looks like this:  
`[script input...] [serialized script] | OP_HASH160 [script hash] OP_EQUAL`  
The equivalent OP\_EVAL script would look like this to old nodes:  
`[script input] [serialized script] | OP_DUP OP_HASH160 [script hash] OP_EQUALVERIFY OP_NOP1`  
Old nodes would only check that the serialized script matches the given script hash when hashed. The other stuff would be ignored.

New nodes would see:  
`[script input] [serialized script] | OP_DUP OP_HASH160 [script hash] OP_EQUALVERIFY OP_EVAL`  
New nodes would understand OP\_EVAL, so they'd check that the serialized script matches the given script *and* execute the serialized script. An OP\_EVAL transaction might be seen as invalid for new nodes and valid for old nodes, but not the other way around. That's what makes it a softfork. If the majority of mining power is using the new rules, then this is not a hardfork because the longest chain will always converge to a state that is valid for both old and new nodes.

Depending on the new opcode's behavior, it may be necessary for new nodes to verify scripts twice to ensure that certain scripts can't cause hardforks. Scripts are verified once using the old script rules and once using the new rules.

The OP\_EVAL proposal was eventually replaced with P2SH because it was discovered that OP\_EVAL accidentally allowed Turing-complete scripts, which the Bitcoin developers didn't want. P2SH is very simple (and a bit weird) in part so that similar accidents would be easy to avoid. But there wasn't any technical problem with this method of adding a new opcode. Moreover, there's nothing restricting the behavior of new opcodes. For example, OP\_EVAL could have interpreted its input in a different, Turing-complete language, though there are various reasons why this might not have been a good idea.

> **Comments:**
> **username_0**: Thanks username_1 - does this mean that "pay to anyone" transactions are completely replaced by P2SH? Looking at this code blob... https://github.com/bitcoin/bitcoin/blob/cd9114e5136ecc1f60baa43fffeeb632782f2353/src/script/script.cpp#L214-L221  
> **username_1**: @username_0 That code checks whether an output script meets the P2SH pattern and therefore requires additional verification. It seems unrelated to pay-to-anyone transactions. There are many ways of sending an output that anyone can redeem. The standard way is output=`OP_TRUE`, but any non-zero constant will work. There isn't much point in doing so, but you could use P2SH if you want: `OP_HASH160 [hash of OP_TRUE script] OP_EQUAL`.  
> **username_0**: I guess what I meant was, is it still possible to use `OP_HASH160 [HASH OF SOMETHING] OP_EQUAL` as an output script if the `SOMETHING` is *not* a valid script (could be any data) like, https://en.bitcoin.it/wiki/Script#Transaction_puzzle  
> **username_1**: @username_0 No, but if you want to do that you can just add some junk at the start of the script to break the pattern, like `OP_0 OP_HASH160 [HASH OF SOMETHING] OP_EQUAL`.  
> **username_1**: (I just noticed that the script I posted in my previous comment is actually unspendable. Change OP_0 to OP_NOP.)  

---

### Answer by username_2 on 2014-11-02. Score: 0

The introduction P2SH didn't mean new OP codes nor repurposing old ones.

You cannot change any existing OP code with a soft fork by definition. The only thing you can do is to interpret information for new applications. For example, you can include the hash of a document to create a proof of existence scheme.

> **Comments:**
> **username_3**: `The introduction P2SH didn't mean new OP codes nor repurposing old ones.` That's technically true (we didn't repurpose `OP_EQUAL`, we repurposed `OP_HASH160 <data> OP_EQUAL`) but it's awfully misleading.  
> **username_0**: username_3 do you agree with username_2 that OP codes can't be repurposed without a hard fork? Say in the context of adding side chain support?  
> **username_0**: Turning a No-Op into OP_SPVVERIFY, etc  
> **username_4**: Maybe clarify the answer to point out that a [soft fork](https://bitcoin.org/en/developer-guide#consensus-rule-changes) requires upgraded nodes to comply with the same rules non-upgrade nodes follow, but that the upgraded nodes can also place additional limitations on how an op code is used.  For example, `op_hash160 <20 bytes> op_equal` retained their original meaning for non-upgraded nodes, but upgrade nodes only allowed spending a P2SH scriptPubKey if the spending scriptSig contained a redeemScript that didn't return false.  

---

