<p>OP_IF and OP_NOTIF always remove the top stack element.</p>

<p>Note that this is a non-standard transaction and may not be relayed by the network.  It would be interesting to see what happens.</p>

CC BY-SA 3.0
2014-03-31T16:35:22.483Z
Using your suggestion I think OP_VERIFY is applied to HASH160(A) for HASH160(A)=B; the duplication of a TRUE result from the first OP_EQUAL is popped by the OP_NOTIF and the original TRUE result of the first OP_EQUAL is then popped by the ELSE OP_DROP *before* the OP_VERIFY...or am I reading your script incorrectly? 

Is it OK to do that with OP_VERIFY; the bitcoin wiki seems to suggest that the OP_VERIFY argument is only(?) either '0' (i.e. OP_FALSE) or '1' (i.e. OP_TRUE), rather than being as general as *any* non-zero argument being treated as TRUE?
Phil Dann Ward
CC BY-SA 3.0
2014-03-31T17:02:36.923Z
OP_VERIFY considers any non-zero value to be TRUE.  See my comment on your question for a script that I think will also work.
ScripterRon
CC BY-SA 3.0
2014-03-31T20:09:54.280Z
I'm still trying to get my newbie brain to understand the subtleties of bitcoin scripting so, out of interest, would your previous version of the script that OP_VERIFYed HASH160(A) have gone wrong if, by some amazing (non?) coincidence, HASH160(A)=B=OP_0? Or is HASH160(A)=OP_0 impossible?
Phil Dann Ward
CC BY-SA 3.0
2014-03-31T21:39:48.970Z
I think it would be safe to assume the hash would not be zero.  I'm not a mathematician, so I can't tell you if a zero result is impossible.  But a zero hash is used in several parts of the bitcoin protocol to indicate no hash value was provided (the 'getblocks' message for example)
ScripterRon
CC BY-SA 3.0
2014-03-31T21:48:48.963Z
So, to answer your question, you could remove the OP_ELSE clause in the above script and it would still work.  As long as the top stack element is non-zero, OP_VERIFY will succeed.
ScripterRon
CC BY-SA 3.0
2014-03-31T15:56:45.900Z
2014-03-31T16:02:12.867Z
2014-03-31T16:02:12.867Z
ScripterRon
<p>So your inputs are:</p>

<pre><code>&lt;sig&gt; &lt;pubkey&gt; &lt;a&gt;
</code></pre>

<p>And you want to verify that Hash160(a) == Hash1 or Hash2, and that sig is a valid signature by pubkey? Based on your original script, it looks like you also want to verify that pubkey matches a hash in the script.</p>

<p>So, the best way to do this is like this:</p>

<pre><code>OP_HASH160 OP_DUP &lt;Hash1&gt; OP_EQUAL
// stack now has &lt;sig&gt; &lt;pubkey&gt; &lt;Hash160(a)&gt; &lt;Hash160(a)==Hash1&gt;
OP_SWAP
// stack now has &lt;sig&gt; &lt;pubkey&gt; &lt;Hash160(a)==Hash1&gt; &lt;Hash160(a)&gt;
&lt;Hash2&gt; OP_EQUAL
// stack now has &lt;sig&gt; &lt;pubkey&gt; &lt;Hash160(a)==Hash1&gt; &lt;Hash160(a)==Hash2&gt;
OP_BOOLOR
// stack now has &lt;sig&gt; &lt;pubkey&gt; &lt;Hash160(a)==Hash1 OR Hash160(a)==Hash2&gt;
OP_VERIFY
// stack now contains &lt;sig&gt; &lt;pubkey&gt;, and if &lt;a&gt; didn't pass the test the transaction has already failed
// now just do a norma pay-to-pubkey-hash for the rest of it
OP_DUP OP_HASH160 &lt;Hash160(pubkey)&gt; OP_EQUALVERIFY OP_CHECKSIGVERIFY
</code></pre>

<p>(I realize this is an old question, but I didn't see that until I'd already written up the script for it, so I'm posting anyway...)</p>

CC BY-SA 3.0
2014-10-27T21:17:54.083Z
`I realize this is an old question` Don't worry about it! There's nothing wrong with answering old questions - there's a badge for it, actually. +1
Nick ODell
CC BY-SA 3.0
2014-10-27T19:50:16.547Z
2014-10-27T19:50:16.547Z
justarandomgeek
<p>I'm trying to write a scriptPubKey for a transaction which checks that the hash of the top value in the scriptSig is equal to <em>either</em> one of two fixed values and if so will do the normal transaction signature checks to allow the owner of a specific bitcoin address to spend them; if the scriptSig value is not equal to either one of the fixed values then the spending transaction should be marked as invalid.</p>

<p>I'm trying to keep the scriptPubKey as small as possible, i.e. avoiding hard-coded duplications of pubKeyHash and/or duplications of large chunks of scripting.</p>

<p>Here's what I've got so far...</p>

<p>scriptPubKey:</p>

<pre><code>OP_HASH160 OP_DUP &lt;B&gt; OP_EQUAL OP_DUP
OP_NOTIF OP_DROP OP_DUP &lt;C&gt; OP_EQUAL OP_ENDIF
OP_VERIFY OP_DROP
OP_DUP OP_HASH160 &lt;pubKeyHash&gt; OP_EQUALVERIFY OP_CHECKSIG
</code></pre>

<p>The scriptSig would look like this...</p>

<p>scriptSig:</p>

<pre><code>&lt;sig&gt; &lt;pubKey&gt; &lt;A&gt;
</code></pre>

<p>The intention is that the transaction would pay out if ( HASH160(A)=B <em>or</em> HASH160(A)=C ) <em>and</em> sig, pubKey and pubKeyHash were all valid in the normal way.</p>

<p>My worry arises from OP_NOTIF; the scripting section of the Bitcoin wiki says that OP_NOTIF removes the top stack value...I assume that it is removed as the OP_NOTIF evaluates it and it is removed regardless of whether it is TRUE or FALSE. Is that correct?</p>

<p>The latter assumption is why I've duplicated the result of the first OP_EQUAL so that I can OP_VERIFY it after the conditional line (assuming that it was TRUE and hasn't otherwise been OP_DROPped by the conditional line).</p>

<p>Would my proposed scriptPubKey have the desired result (without nasty side effects) or is there something smaller/simpler (e.g. using OP_IFDUP instead of an OP_DUP and a conditional OP_DROP) or, if my script is plain wrong, what would a workable script look like?</p>

<p>I should say that the point of this transaction is not to effect a multi-<em>signature</em> transaction; it's to effect a kind of single-signature <em>plus</em> 1-of-2 'passwords' transaction.</p>

CC BY-SA 3.0
2014-03-31T16:17:14.110Z
Another approach: OP_HASH160 OP_DUP <B> OP_EQUAL OP_NOTIF <C> OP_EQUAL OP_ELSE OP_DROP OP_1 OP_ENDIF OP_VERIFY OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
ScripterRon
<script>
Conditional scripting: how does OP_NOTIF (and OP_IF) operation(s) affect the stack?
Phil Dann Ward
# Conditional scripting: how does OP_NOTIF (and OP_IF) operation(s) affect the stack?

(Asked by: username_0 on 2014-03-31)

I'm trying to write a scriptPubKey for a transaction which checks that the hash of the top value in the scriptSig is equal to *either* one of two fixed values and if so will do the normal transaction signature checks to allow the owner of a specific bitcoin address to spend them; if the scriptSig value is not equal to either one of the fixed values then the spending transaction should be marked as invalid.

I'm trying to keep the scriptPubKey as small as possible, i.e. avoiding hard-coded duplications of pubKeyHash and/or duplications of large chunks of scripting.

Here's what I've got so far...

scriptPubKey:

```
OP_HASH160 OP_DUP <B> OP_EQUAL OP_DUP
OP_NOTIF OP_DROP OP_DUP <C> OP_EQUAL OP_ENDIF
OP_VERIFY OP_DROP
OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG

```

The scriptSig would look like this...

scriptSig:

```
<sig> <pubKey> <A>

```

The intention is that the transaction would pay out if ( HASH160(A)=B *or* HASH160(A)=C ) *and* sig, pubKey and pubKeyHash were all valid in the normal way.

My worry arises from OP\_NOTIF; the scripting section of the Bitcoin wiki says that OP\_NOTIF removes the top stack value...I assume that it is removed as the OP\_NOTIF evaluates it and it is removed regardless of whether it is TRUE or FALSE. Is that correct?

The latter assumption is why I've duplicated the result of the first OP\_EQUAL so that I can OP\_VERIFY it after the conditional line (assuming that it was TRUE and hasn't otherwise been OP\_DROPped by the conditional line).

Would my proposed scriptPubKey have the desired result (without nasty side effects) or is there something smaller/simpler (e.g. using OP\_IFDUP instead of an OP\_DUP and a conditional OP\_DROP) or, if my script is plain wrong, what would a workable script look like?

I should say that the point of this transaction is not to effect a multi-*signature* transaction; it's to effect a kind of single-signature *plus* 1-of-2 'passwords' transaction.

**Tags:** script

> **Comments:**
> **username_1**: Another approach: OP_HASH160 OP_DUP <B> OP_EQUAL OP_NOTIF <C> OP_EQUAL OP_ELSE OP_DROP OP_1 OP_ENDIF OP_VERIFY OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG  

---

## 2 answers

### Answer by username_1 on 2014-03-31. Score: 1 | Accepted answer

OP\_IF and OP\_NOTIF always remove the top stack element.

Note that this is a non-standard transaction and may not be relayed by the network. It would be interesting to see what happens.

> **Comments:**
> **username_0**: Using your suggestion I think OP_VERIFY is applied to HASH160(A) for HASH160(A)=B; the duplication of a TRUE result from the first OP_EQUAL is popped by the OP_NOTIF and the original TRUE result of the first OP_EQUAL is then popped by the ELSE OP_DROP *before* the OP_VERIFY...or am I reading your script incorrectly?   Is it OK to do that with OP_VERIFY; the bitcoin wiki seems to suggest that the OP_VERIFY argument is only(?) either '0' (i.e. OP_FALSE) or '1' (i.e. OP_TRUE), rather than being as general as *any* non-zero argument being treated as TRUE?  
> **username_1**: OP_VERIFY considers any non-zero value to be TRUE.  See my comment on your question for a script that I think will also work.  
> **username_0**: I'm still trying to get my newbie brain to understand the subtleties of bitcoin scripting so, out of interest, would your previous version of the script that OP_VERIFYed HASH160(A) have gone wrong if, by some amazing (non?) coincidence, HASH160(A)=B=OP_0? Or is HASH160(A)=OP_0 impossible?  
> **username_1**: I think it would be safe to assume the hash would not be zero.  I'm not a mathematician, so I can't tell you if a zero result is impossible.  But a zero hash is used in several parts of the bitcoin protocol to indicate no hash value was provided (the 'getblocks' message for example)  
> **username_1**: So, to answer your question, you could remove the OP_ELSE clause in the above script and it would still work.  As long as the top stack element is non-zero, OP_VERIFY will succeed.  

---

### Answer by username_2 on 2014-10-27. Score: 2

So your inputs are:

```
<sig> <pubkey> <a>

```

And you want to verify that Hash160(a) == Hash1 or Hash2, and that sig is a valid signature by pubkey? Based on your original script, it looks like you also want to verify that pubkey matches a hash in the script.

So, the best way to do this is like this:

```
OP_HASH160 OP_DUP <Hash1> OP_EQUAL
// stack now has <sig> <pubkey> <Hash160(a)> <Hash160(a)==Hash1>
OP_SWAP
// stack now has <sig> <pubkey> <Hash160(a)==Hash1> <Hash160(a)>
<Hash2> OP_EQUAL
// stack now has <sig> <pubkey> <Hash160(a)==Hash1> <Hash160(a)==Hash2>
OP_BOOLOR
// stack now has <sig> <pubkey> <Hash160(a)==Hash1 OR Hash160(a)==Hash2>
OP_VERIFY
// stack now contains <sig> <pubkey>, and if <a> didn't pass the test the transaction has already failed
// now just do a norma pay-to-pubkey-hash for the rest of it
OP_DUP OP_HASH160 <Hash160(pubkey)> OP_EQUALVERIFY OP_CHECKSIGVERIFY

```

(I realize this is an old question, but I didn't see that until I'd already written up the script for it, so I'm posting anyway...)

> **Comments:**
> **username_3**: `I realize this is an old question` Don't worry about it! There's nothing wrong with answering old questions - there's a badge for it, actually. +1  

---

