<h1>How to use <code>OP_BOOLOR</code> and <code>OP_EQUAL</code>?</h1>

<p>You can see the actual implementation for script opcodes in <a href="https://github.com/bitcoin/bitcoin/blob/master/src/script.cpp" rel="nofollow">Bitcoin's script.cpp</a>.</p>

<p><code>OP_BOOLOR</code> does this:</p>

<pre><code>[...]
CBigNum bn1 = CastToBigNum(stacktop(-2));
CBigNum bn2 = CastToBigNum(stacktop(-1));
CBigNum bn;
[...]
case OP_BOOLOR:              bn = (bn1 != bnZero || bn2 != bnZero); break;
[...]
popstack(stack);
popstack(stack);
stack.push_back(bn.getvch());
[...]
</code></pre>

<p>So it's effectively reading from the stack, popping the values and pushing the result.</p>

<p><code>OP_EQUAL</code> is pretty much the same:</p>

<pre><code>[...]
popstack(stack);
popstack(stack);
stack.push_back(fEqual ? vchTrue : vchFalse);
[...]
</code></pre>

<p>It's popping two values from the top and pushing the result of the comparison.</p>

<hr>

<h1>Is the script correct?</h1>

<p>Let's run the scripts and see what happens! <code>scriptSig</code> is executed first:</p>

<pre><code>scriptSig: [Wallet] [Wallet] [sig] [pubKey]
</code></pre>

<p>This code is just pushing into the stack, so after the <code>scriptSig</code> runs the stack looks like this:</p>

<pre><code>[pubKey] &lt;- TOP OF THE STACK
[sig]
[Wallet]
[Wallet]
</code></pre>

<p>Notice the elements are reversed. <strong>The first thing pushed goes to the bottom of the stack.</strong></p>

<p>Now <code>scriptPubKey</code> is run keeping the contents of the stack resulting from running <code>scriptSig</code>. If we do that with your script...</p>

<pre><code>scriptPubKey: OP_EQUAL Wallet1_Value [Wallet] 
              OP_EQUAL Wallet2_Value [Wallet] 
              OP_BOOLOR 
              OP_VERIFY OP_DUP OP_HASH160 [pubKeyHash] OP_EQUALVERIFY OP_CHECKSIG
</code></pre>

<p>...the first thing that gets executed is <code>OP_EQUAL</code>, which compares the top two elements of the stack <code>[pubKey]  [sig]</code> which are obviously not equal so <code>0</code> (false) is pushed. <strong>I'll just stop here</strong> since it won't make sense at all to continue.</p>

<hr>

<h1>Building the correct script</h1>

<p>I guessed what you actually meant to do, and this are my proposed scripts.</p>

<p>First, I guess the spending user supplies <code>[sig]</code>, <code>[pubKey]</code> and <code>[Wallet]</code> where <code>[Wallet]</code> is either <code>Wallet1_Value</code> or <code>Wallet2_Value</code> to be able to spend the funds:</p>

<pre><code>scriptSig: [sig] [pubKey] [Wallet]

Final stack after running:
    [Wallet] &lt;- TOP OF THE STACK
    [pubKey]
    [sig]
</code></pre>

<p>That's <code>scriptSig</code>, and <strong>it's what a user supplies when he wants to spend the funds</strong>. We're done! Let's build the next step, i.e. the <code>scriptPubKey</code> that checks if the supplied values are fine.</p>

<p>The first thing you want to do is to check whether <code>[Wallet]</code> is one of <code>Wallet1_Value</code> or <code>Wallet2_Value</code>. First let's duplicate <code>[Wallet]</code> so we can check it twice. The first step in <code>scriptPubKey</code> is <code>OP_DUP</code>. Let's run both <code>scriptSig</code> first and the the new <code>scriptPubKey</code>:</p>

<pre><code>scriptSig: [sig] [pubKey] [Wallet]
scriptPubKey: OP_DUP 

Final stack:
    [Wallet] &lt;- TOP OF THE STACK
    [Wallet]
    [pubKey]
    [sig]
</code></pre>

<p>Of course we want to check it against <code>Wallet1_Value</code> first:</p>

<pre><code>scriptSig: [sig] [pubKey] [Wallet]
scriptPubKey: OP_DUP [Wallet1_value]

Final stack:
    Wallet1_Value &lt;- TOP OF THE STACK
    [Wallet]
    [Wallet]
    [pubKey]
    [sig]
</code></pre>

<p>And now check the top two items for equality:</p>

<pre><code>scriptSig: [sig] [pubKey] [Wallet]
scriptPubKey: OP_DUP [Wallet1_value] OP_EQUAL

Final stack:
    (== Wallet1, either TRUE or FALSE) &lt;- TOP OF THE STACK
    [Wallet]
    [pubKey]
    [sig]
</code></pre>

<p>Now we want to check the duplicate <code>[Wallet]</code> against <code>Wallet2_value</code> but the previous result is at the top of the stack. We must swap it first using <code>OP_SWAP</code>:</p>

<pre><code>scriptSig: [sig] [pubKey] [Wallet]
scriptPubKey: OP_DUP [Wallet1_value] OP_EQUAL OP_SWAP

Final stack:
    [Wallet] &lt;- TOP OF THE STACK
    (== Wallet1)
    [pubKey]
    [sig]
</code></pre>

<p>Again, we push the value we want to check, and <code>OP_EQUAL</code> it:</p>

<pre><code>scriptSig: [sig] [pubKey] [Wallet]
scriptPubKey: OP_DUP [Wallet1_value] OP_EQUAL OP_SWAP [Wallet2_value] OP_EQUAL

Final stack:
    (== Wallet2) &lt;- TOP OF THE STACK
    (== Wallet1)
    [pubKey]
    [sig]
</code></pre>

<p>The script is pretty much done. Now just <code>OP_BOOLOR OP_VERIFY</code>:</p>

<pre><code>scriptSig: [sig] [pubKey] [Wallet]
scriptPubKey: OP_DUP [Wallet1_value] OP_EQUAL OP_SWAP [Wallet2_value] OP_EQUAL OP_BOOLOR OP_VERIFY
</code></pre>

<p>If <code>OP_VERIFY</code> finds <code>FALSE</code> at the top of the stack it will reject the transaction. If it finds <code>TRUE</code> the script continues and the stack looks like this:</p>

<pre><code>Final stack if correct [Wallet] was provided:
    [pubKey]
    [sig]
</code></pre>

<p><strong>Which is what the stack looks like after a regular <code>scriptSig</code>!</strong> So the rest of the <code>scriptPubKey</code> is just a regular <code>pay-to-pubkey-hash</code> script. The final <code>scriptPubKey</code> is:</p>

<pre><code>OP_DUP [Wallet1_value] OP_EQUAL OP_SWAP [Wallet2_value] OP_EQUAL OP_BOOLOR OP_VERIFY
OP_DUP OP_HASH160 [pubKeyHash] OP_EQUALVERIFY OP_CHECKSIG
</code></pre>

<hr>

<h1>Actual security</h1>

<p>Now, regardless of the order, <strong>the script is not very secure</strong>. I get this might just be an exercise in understanding scripts or is not meant to be secure (it might be only a check to avoid spending from unwanted wallets) but I think it's important to show how this is actually not secure at all.</p>

<p>Whenever you publish a transaction using this scheme, the output <code>scriptPubKey</code> is <strong>publicly available</strong> and looks like this:</p>

<pre><code>OP_DUP [Wallet1_value] OP_EQUAL OP_SWAP [Wallet2_value] OP_EQUAL OP_BOOLOR OP_VERIFY
OP_DUP OP_HASH160 [pubKeyHash] OP_EQUALVERIFY OP_CHECKSIG
</code></pre>

<p>Both <code>Wallet1_value</code> and <code>Wallet2_value</code> are public for anyone to see in the blockchain! The security still depends <strong>ONLY</strong> on <code>[sig] [pubKey]</code> since I know exactly what's required to spend the transaction, i.e. <strong>the script security is equivalent to a regular</strong> <code>pay-to-pubkey-hash</code> <strong>transaction!</strong></p>

<hr>

<h1>EDIT: A little bit safer (response to comment)</h1>

<blockquote>
  <p>Could you require Wallet1_value and Wallet2_value be hashes instead? Then the scriptsig would have to supply a hash of one of the two wallets.</p>
</blockquote>

<p>Yes. Actually it's very easy (changes shown in <strong>bold face</strong>):</p>

<p><strong>OP_HASH256</strong> OP_DUP [Wallet1_<strong>hash</strong>] OP_EQUAL OP_SWAP [Wallet2_<strong>hash</strong>] OP_EQUAL OP_BOOLOR OP_VERIFY OP_DUP OP_HASH160 [pubKeyHash] OP_EQUALVERIFY OP_CHECKSIG</p>

<p>As you can see the top of the stack is hashed (<code>OP_HASH160</code> or <code>OP_HASH256</code>, whichever you prefer) before duplication, so now you can compare the provided data to match with one of two hashes instead of values.</p>

<p>This is a bit better since the data is not there in plain sight. You would have to brute-force to find one of <code>WalletN_hash</code>. The problem is as soon as you spend it, the <code>WalletN_value</code> becomes public in the spending transaction, so <code>WalletN_hash</code> can't be used in a transaction again! It would be one-use only. If you published several transactions with the same <code>WalletN_hash</code>, you'd have to spend all outputs at the same time or else the unspent ones might be hijacked.</p>

<p>Bear in mind the scheme is still secure because there are signatures involved. If the <code>scriptPubKey</code> lacked the standard signatue verification it would just be:</p>

<pre><code>OP_HASH256 OP_DUP Wallet1_hash OP_EQUAL OP_SWAP Wallet2_hash OP_EQUAL OP_BOOLOR OP_VERIFY
</code></pre>

<p>Any miner could listen for this type of transactions and, as soon as anyone tried to spend one with <code>scriptSig = [WalletN_value]</code>, the transaction could be modified <strong>(even the outputs!)</strong> instead of relaying it since the transaction is not signed at all, so the miner could redeem the outputs himself.</p>

CC BY-SA 3.0
2014-01-14T13:15:23.707Z
So with this script, could the output be hijacked? Or is your security argument at the end more focused on privacy of addresses?
Scrybe
CC BY-SA 3.0
2014-01-14T14:17:05.727Z
@CoinEnablers the security is the same as a regular transaction. No more, no less. You can't hijack it just like you can't hijack a regular transaction (since it's still using the regular `OP_CHECKSIG` part) but my point is there's no extra security either (even if it has the extra wallet check) because it's checking against a value that's public.
kaoD
CC BY-SA 3.0
2014-01-15T02:36:53.230Z
@kaoD, that is exactly what I was looking for! Extending the exercise a little bit more, what would be a good solution to the security points you bring up? Could you require Wallet1_value and Wallet2_value be hashes instead? Then the scriptsig would have to supply a hash of one of the two wallets.  Thanks again for the thorough explanation!
Lull3rSkat3r
CC BY-SA 3.0
2014-01-15T03:20:55.023Z
@Lull3rSkat3r sure. I updated the answer with a new section! Let me know if you have any more questions :) By the way, I don't know what's `WalletN_value` but I just assume it's a bunch of binary data (any data will do, hope that's clear, I just kept using `Wallet` because it's what you called them but there's no way to access Bitcoin wallet from a script).
kaoD
CC BY-SA 3.0
2014-01-15T04:41:38.567Z
Awesome! I definitely have a better understanding now. In regards to my thought process about the value of `Wallet`, I was assuming the client would have some interface for the value. The client would add it to scriptsig similar to how `sig` and `pubKey` are added in the vanilla client.
Lull3rSkat3r
CC BY-SA 3.0
2014-01-15T05:13:42.727Z
@Lull3rSkat3r nope. Unfortunately Bitcoin scripts are quite limited and don't have an API/variables (neither inwards nor outwards). The only way to read/write data is through value literals, and the only values that Bitcoin-Qt pushes in transactions are the regular `[sig]` and `[pubkey]` (because they're core to Bitcoin). Of course you could craft your own wallet which generates/spends this special kind of transactions! Whether you push `WalletN` or `YourPassword` is just a matter of choice. Bitcoin scripts will only see a bunch of data, whatever it is!
kaoD
CC BY-SA 3.0
2014-01-14T10:11:05.127Z
2014-01-15T03:26:01.557Z
2014-01-15T03:26:01.557Z
kaoD
<p>I am trying to write a script that will allow the receiver of my coins to only spend them on two wallets I specify. After that check has been done I want to perform the usual verification that the current client does to verify a transaction. This is where I am at, but I am not sure if things are in the right order, if OP_EQUAL pushes to the stack, and if OP_BOOLOR reads from it. </p>

<pre><code>scriptPubKey: OP_EQUAL Wallet1_Value [Wallet] 
              OP_EQUAL Wallet2_Value [Wallet] 
              OP_BOOLOR 
              OP_VERIFY OP_DUP OP_HASH160 [pubKeyHash] OP_EQUALVERIFY OP_CHECKSIG

scriptSig: [Wallet] [Wallet] [sig] [pubKey]
</code></pre>

<transactions><script>
Script To Limit Transactions To Specific Wallets
Lull3rSkat3r
# Script To Limit Transactions To Specific Wallets

(Asked by: username_0 on 2014-01-14)

I am trying to write a script that will allow the receiver of my coins to only spend them on two wallets I specify. After that check has been done I want to perform the usual verification that the current client does to verify a transaction. This is where I am at, but I am not sure if things are in the right order, if OP\_EQUAL pushes to the stack, and if OP\_BOOLOR reads from it.

```
scriptPubKey: OP_EQUAL Wallet1_Value [Wallet] 
              OP_EQUAL Wallet2_Value [Wallet] 
              OP_BOOLOR 
              OP_VERIFY OP_DUP OP_HASH160 [pubKeyHash] OP_EQUALVERIFY OP_CHECKSIG

scriptSig: [Wallet] [Wallet] [sig] [pubKey]

```

**Tags:** transactions, script


---

## 1 answers

### Answer by username_1 on 2014-01-14. Score: 1 | Accepted answer

# How to use `OP_BOOLOR` and `OP_EQUAL`?

You can see the actual implementation for script opcodes in [Bitcoin's script.cpp](https://github.com/bitcoin/bitcoin/blob/master/src/script.cpp).

`OP_BOOLOR` does this:

```
[...]
CBigNum bn1 = CastToBigNum(stacktop(-2));
CBigNum bn2 = CastToBigNum(stacktop(-1));
CBigNum bn;
[...]
case OP_BOOLOR:              bn = (bn1 != bnZero || bn2 != bnZero); break;
[...]
popstack(stack);
popstack(stack);
stack.push_back(bn.getvch());
[...]

```

So it's effectively reading from the stack, popping the values and pushing the result.

`OP_EQUAL` is pretty much the same:

```
[...]
popstack(stack);
popstack(stack);
stack.push_back(fEqual ? vchTrue : vchFalse);
[...]

```

It's popping two values from the top and pushing the result of the comparison.

---

# Is the script correct?

Let's run the scripts and see what happens! `scriptSig` is executed first:

```
scriptSig: [Wallet] [Wallet] [sig] [pubKey]

```

This code is just pushing into the stack, so after the `scriptSig` runs the stack looks like this:

```
[pubKey] <- TOP OF THE STACK
[sig]
[Wallet]
[Wallet]

```

Notice the elements are reversed. **The first thing pushed goes to the bottom of the stack.**

Now `scriptPubKey` is run keeping the contents of the stack resulting from running `scriptSig`. If we do that with your script...

```
scriptPubKey: OP_EQUAL Wallet1_Value [Wallet] 
              OP_EQUAL Wallet2_Value [Wallet] 
              OP_BOOLOR 
              OP_VERIFY OP_DUP OP_HASH160 [pubKeyHash] OP_EQUALVERIFY OP_CHECKSIG

```

...the first thing that gets executed is `OP_EQUAL`, which compares the top two elements of the stack `[pubKey] [sig]` which are obviously not equal so `0` (false) is pushed. **I'll just stop here** since it won't make sense at all to continue.

---

# Building the correct script

I guessed what you actually meant to do, and this are my proposed scripts.

First, I guess the spending user supplies `[sig]`, `[pubKey]` and `[Wallet]` where `[Wallet]` is either `Wallet1_Value` or `Wallet2_Value` to be able to spend the funds:

```
scriptSig: [sig] [pubKey] [Wallet]

Final stack after running:
    [Wallet] <- TOP OF THE STACK
    [pubKey]
    [sig]

```

That's `scriptSig`, and **it's what a user supplies when he wants to spend the funds**. We're done! Let's build the next step, i.e. the `scriptPubKey` that checks if the supplied values are fine.

The first thing you want to do is to check whether `[Wallet]` is one of `Wallet1_Value` or `Wallet2_Value`. First let's duplicate `[Wallet]` so we can check it twice. The first step in `scriptPubKey` is `OP_DUP`. Let's run both `scriptSig` first and the the new `scriptPubKey`:

```
scriptSig: [sig] [pubKey] [Wallet]
scriptPubKey: OP_DUP 

Final stack:
    [Wallet] <- TOP OF THE STACK
    [Wallet]
    [pubKey]
    [sig]

```

Of course we want to check it against `Wallet1_Value` first:

```
scriptSig: [sig] [pubKey] [Wallet]
scriptPubKey: OP_DUP [Wallet1_value]

Final stack:
    Wallet1_Value <- TOP OF THE STACK
    [Wallet]
    [Wallet]
    [pubKey]
    [sig]

```

And now check the top two items for equality:

```
scriptSig: [sig] [pubKey] [Wallet]
scriptPubKey: OP_DUP [Wallet1_value] OP_EQUAL

Final stack:
    (== Wallet1, either TRUE or FALSE) <- TOP OF THE STACK
    [Wallet]
    [pubKey]
    [sig]

```

Now we want to check the duplicate `[Wallet]` against `Wallet2_value` but the previous result is at the top of the stack. We must swap it first using `OP_SWAP`:

```
scriptSig: [sig] [pubKey] [Wallet]
scriptPubKey: OP_DUP [Wallet1_value] OP_EQUAL OP_SWAP

Final stack:
    [Wallet] <- TOP OF THE STACK
    (== Wallet1)
    [pubKey]
    [sig]

```

Again, we push the value we want to check, and `OP_EQUAL` it:

```
scriptSig: [sig] [pubKey] [Wallet]
scriptPubKey: OP_DUP [Wallet1_value] OP_EQUAL OP_SWAP [Wallet2_value] OP_EQUAL

Final stack:
    (== Wallet2) <- TOP OF THE STACK
    (== Wallet1)
    [pubKey]
    [sig]

```

The script is pretty much done. Now just `OP_BOOLOR OP_VERIFY`:

```
scriptSig: [sig] [pubKey] [Wallet]
scriptPubKey: OP_DUP [Wallet1_value] OP_EQUAL OP_SWAP [Wallet2_value] OP_EQUAL OP_BOOLOR OP_VERIFY

```

If `OP_VERIFY` finds `FALSE` at the top of the stack it will reject the transaction. If it finds `TRUE` the script continues and the stack looks like this:

```
Final stack if correct [Wallet] was provided:
    [pubKey]
    [sig]

```

**Which is what the stack looks like after a regular `scriptSig`!** So the rest of the `scriptPubKey` is just a regular `pay-to-pubkey-hash` script. The final `scriptPubKey` is:

```
OP_DUP [Wallet1_value] OP_EQUAL OP_SWAP [Wallet2_value] OP_EQUAL OP_BOOLOR OP_VERIFY
OP_DUP OP_HASH160 [pubKeyHash] OP_EQUALVERIFY OP_CHECKSIG

```

---

# Actual security

Now, regardless of the order, **the script is not very secure**. I get this might just be an exercise in understanding scripts or is not meant to be secure (it might be only a check to avoid spending from unwanted wallets) but I think it's important to show how this is actually not secure at all.

Whenever you publish a transaction using this scheme, the output `scriptPubKey` is **publicly available** and looks like this:

```
OP_DUP [Wallet1_value] OP_EQUAL OP_SWAP [Wallet2_value] OP_EQUAL OP_BOOLOR OP_VERIFY
OP_DUP OP_HASH160 [pubKeyHash] OP_EQUALVERIFY OP_CHECKSIG

```

Both `Wallet1_value` and `Wallet2_value` are public for anyone to see in the blockchain! The security still depends **ONLY** on `[sig] [pubKey]` since I know exactly what's required to spend the transaction, i.e. **the script security is equivalent to a regular** `pay-to-pubkey-hash` **transaction!**

---

# EDIT: A little bit safer (response to comment)

> Could you require Wallet1\_value and Wallet2\_value be hashes instead? Then the scriptsig would have to supply a hash of one of the two wallets.

Yes. Actually it's very easy (changes shown in **bold face**):

**OP\_HASH256** OP\_DUP [Wallet1\_**hash**] OP\_EQUAL OP\_SWAP [Wallet2\_**hash**] OP\_EQUAL OP\_BOOLOR OP\_VERIFY OP\_DUP OP\_HASH160 [pubKeyHash] OP\_EQUALVERIFY OP\_CHECKSIG

As you can see the top of the stack is hashed (`OP_HASH160` or `OP_HASH256`, whichever you prefer) before duplication, so now you can compare the provided data to match with one of two hashes instead of values.

This is a bit better since the data is not there in plain sight. You would have to brute-force to find one of `WalletN_hash`. The problem is as soon as you spend it, the `WalletN_value` becomes public in the spending transaction, so `WalletN_hash` can't be used in a transaction again! It would be one-use only. If you published several transactions with the same `WalletN_hash`, you'd have to spend all outputs at the same time or else the unspent ones might be hijacked.

Bear in mind the scheme is still secure because there are signatures involved. If the `scriptPubKey` lacked the standard signatue verification it would just be:

```
OP_HASH256 OP_DUP Wallet1_hash OP_EQUAL OP_SWAP Wallet2_hash OP_EQUAL OP_BOOLOR OP_VERIFY

```

Any miner could listen for this type of transactions and, as soon as anyone tried to spend one with `scriptSig = [WalletN_value]`, the transaction could be modified **(even the outputs!)** instead of relaying it since the transaction is not signed at all, so the miner could redeem the outputs himself.

> **Comments:**
> **username_2**: So with this script, could the output be hijacked? Or is your security argument at the end more focused on privacy of addresses?  
> **username_1**: @CoinEnablers the security is the same as a regular transaction. No more, no less. You can't hijack it just like you can't hijack a regular transaction (since it's still using the regular `OP_CHECKSIG` part) but my point is there's no extra security either (even if it has the extra wallet check) because it's checking against a value that's public.  
> **username_0**: @username_1, that is exactly what I was looking for! Extending the exercise a little bit more, what would be a good solution to the security points you bring up? Could you require Wallet1_value and Wallet2_value be hashes instead? Then the scriptsig would have to supply a hash of one of the two wallets.  Thanks again for the thorough explanation!  
> **username_1**: @username_0 sure. I updated the answer with a new section! Let me know if you have any more questions :) By the way, I don't know what's `WalletN_value` but I just assume it's a bunch of binary data (any data will do, hope that's clear, I just kept using `Wallet` because it's what you called them but there's no way to access Bitcoin wallet from a script).  
> **username_0**: Awesome! I definitely have a better understanding now. In regards to my thought process about the value of `Wallet`, I was assuming the client would have some interface for the value. The client would add it to scriptsig similar to how `sig` and `pubKey` are added in the vanilla client.  
> **username_1**: @username_0 nope. Unfortunately Bitcoin scripts are quite limited and don't have an API/variables (neither inwards nor outwards). The only way to read/write data is through value literals, and the only values that Bitcoin-Qt pushes in transactions are the regular `[sig]` and `[pubkey]` (because they're core to Bitcoin). Of course you could craft your own wallet which generates/spends this special kind of transactions! Whether you push `WalletN` or `YourPassword` is just a matter of choice. Bitcoin scripts will only see a bunch of data, whatever it is!  

---

