<p>You might be able to combine a hash lock with a conditional payout.</p>

<p>Here's a somewhat simplified example that shows how to make a payout depend on knowledge of a secret. Bob makes a bet with Alice that she can't guess Bob's secret before a deadline. Alice proves she knows the secret by publishing the preimage to its hash value, which Bob publishes. Alice and Bob each contribute one bitcoin. The winner receives two bitcoin. If Bob doesn't reveal the secret after the deadline, Alice takes all the money.</p>

<p>There are two one-bitcoin inputs, signed respectively by Alice and Bob.</p>

<p>There is one two-bitcoin output. It is protected by a nested conditional challenge script that looks something like this:</p>

<pre><code>IF
  // Alice spends with secret before deadline
  OP_HASH256 &lt;hash&gt; OP_EQUALVERIFY &lt;Alice pubkey&gt; OP_CHECKSIG
ELSE
  // deadline has expired
  &lt;deadline&gt; OP_CHECKLOCKTIMEVERIFY OP_DROP

  IF
    // Bob spends by revealing the secret
    OP_HASH256 &lt;hash&gt; OP_EQUALVERIFY &lt;Bob pubkey&gt; OP_CHECKSIG
  ELSE
    // Alice spends if Bob refuses to publish the secret
    &lt;Alice pubkey&gt; OP_CHECKSIG
  ENDIF
ENDIF
</code></pre>

<p>To spend the output before the deadline, Alice uses this response script:</p>

<pre><code>&lt;Alice signature&gt; &lt;secret&gt; &lt;1&gt;
</code></pre>

<p>After the deadline, Bob uses this response script:</p>

<pre><code>&lt;0&gt; &lt;Bob signature&gt; &lt;secret&gt; &lt;1&gt; &lt;0&gt;
</code></pre>

<p>If Bob fails to spend the output after the deadline (revealing the secret), Alice takes all the money with this response script:</p>

<pre><code>&lt;0&gt; &lt;Alice signature&gt; &lt;0&gt; &lt;0&gt;
</code></pre>

<p>There's a problem with this approach, though. If Alice doesn't guess the secret and Bob publishes it, Alice can use the secret to make her own transaction claiming the output. This sets up a race condition in which Alice and Bob each have pending transactions trying to spend the output.</p>

<p>One way to fix this problem would be to give Bob a grace period immediately after the deadline (say, one day). During the grace period, Alice would be unable to spend, but Bob could.</p>

CC BY-SA 3.0
2017-07-09T08:48:04.617Z
Thank you very much! Nice thinking. However, it partially fixes my problem. If Bob disappears before the checklocktimeverify expires, and no results are published (no secret published) alice should be able to get only her bet back, e.g. 50% of the funds available in the p2sh address. How can this be achieved? Also, is there a limit of how many bits can the secret have? I would like to add like to add some random data to make brute force unworkable. Last but not least, is there some magic that Bob can do so the secret is published at some time regardless if he disappears?
skydanc3r
CC BY-SA 3.0
2017-07-09T00:04:34.163Z
2017-07-09T00:50:26.243Z
2017-07-09T00:50:26.243Z
Rich Apodaca
<p>I am trying to make a smart contract that acts similar to a lottery or gambling game. Here is an example:</p>

<p>Alice and Bob send funds to a P2SH address. Bob is the lottery. The funds needs to be locked for some time (until the draw for example, like 5 days). For this we can use OP_CHECKLOCKTIMEVERIFY. After the nLockTime expires, if Alice guessed 3 numbers, she will get 50% of her deposit back. If she guesses 6 numbers, she will get 200% of her deposit back. </p>

<p>How can Bob (the lottery) commit to some numbers that Alice needs to guess before Alice funds the deposit address? Bob needs to be able to prove that the numbers were chosen before she funded the deposit address, and cannot simply deny any numbers Alice would guess. </p>

<p>On the other side, how can we enforce the funds go back to Alice if she guesses the numbers that were previously committed to by Bob in case Bob disappears before the draw (nLickTime expiration) time comes?</p>

<p>The simplest thing I can think of is Bob puts a hash of the numbers he committed to in OP_RETURN in the transaction funding the deposit address, but this is kind of a PITA and annoying and it does not offer a guarantee for Alice that she will take her money if she guesses the numbers Bob committed to even if he disappears until the draw (nLockTime expire) time comes.</p>

<p>Thank you.</p>

CC BY-SA 3.0
2017-07-09T01:33:45.147Z
If the numbers were quite small, in most cases I can think of there would be nothing stopping Alice attempting multiple guesses until she unlocks the script (bruteforce) which isn't in the spirit of the game you've described.
meshcollider
<p2sh><checklocktimeverify>
What OP code can I use in the scripting system to make a smart contract that acts similar to a lottery
skydanc3r
# What OP code can I use in the scripting system to make a smart contract that acts similar to a lottery

(Asked by: username_0 on 2017-07-08)

I am trying to make a smart contract that acts similar to a lottery or gambling game. Here is an example:

Alice and Bob send funds to a P2SH address. Bob is the lottery. The funds needs to be locked for some time (until the draw for example, like 5 days). For this we can use OP\_CHECKLOCKTIMEVERIFY. After the nLockTime expires, if Alice guessed 3 numbers, she will get 50% of her deposit back. If she guesses 6 numbers, she will get 200% of her deposit back.

How can Bob (the lottery) commit to some numbers that Alice needs to guess before Alice funds the deposit address? Bob needs to be able to prove that the numbers were chosen before she funded the deposit address, and cannot simply deny any numbers Alice would guess.

On the other side, how can we enforce the funds go back to Alice if she guesses the numbers that were previously committed to by Bob in case Bob disappears before the draw (nLickTime expiration) time comes?

The simplest thing I can think of is Bob puts a hash of the numbers he committed to in OP\_RETURN in the transaction funding the deposit address, but this is kind of a PITA and annoying and it does not offer a guarantee for Alice that she will take her money if she guesses the numbers Bob committed to even if he disappears until the draw (nLockTime expire) time comes.

Thank you.

**Tags:** p2sh, checklocktimeverify

> **Comments:**
> **username_1**: If the numbers were quite small, in most cases I can think of there would be nothing stopping Alice attempting multiple guesses until she unlocks the script (bruteforce) which isn't in the spirit of the game you've described.  

---

## 1 answers

### Answer by username_2 on 2017-07-09. Score: 1 | Accepted answer

You might be able to combine a hash lock with a conditional payout.

Here's a somewhat simplified example that shows how to make a payout depend on knowledge of a secret. Bob makes a bet with Alice that she can't guess Bob's secret before a deadline. Alice proves she knows the secret by publishing the preimage to its hash value, which Bob publishes. Alice and Bob each contribute one bitcoin. The winner receives two bitcoin. If Bob doesn't reveal the secret after the deadline, Alice takes all the money.

There are two one-bitcoin inputs, signed respectively by Alice and Bob.

There is one two-bitcoin output. It is protected by a nested conditional challenge script that looks something like this:

```
IF
  // Alice spends with secret before deadline
  OP_HASH256 <hash> OP_EQUALVERIFY <Alice pubkey> OP_CHECKSIG
ELSE
  // deadline has expired
  <deadline> OP_CHECKLOCKTIMEVERIFY OP_DROP

  IF
    // Bob spends by revealing the secret
    OP_HASH256 <hash> OP_EQUALVERIFY <Bob pubkey> OP_CHECKSIG
  ELSE
    // Alice spends if Bob refuses to publish the secret
    <Alice pubkey> OP_CHECKSIG
  ENDIF
ENDIF

```

To spend the output before the deadline, Alice uses this response script:

```
<Alice signature> <secret> <1>

```

After the deadline, Bob uses this response script:

```
<0> <Bob signature> <secret> <1> <0>

```

If Bob fails to spend the output after the deadline (revealing the secret), Alice takes all the money with this response script:

```
<0> <Alice signature> <0> <0>

```

There's a problem with this approach, though. If Alice doesn't guess the secret and Bob publishes it, Alice can use the secret to make her own transaction claiming the output. This sets up a race condition in which Alice and Bob each have pending transactions trying to spend the output.

One way to fix this problem would be to give Bob a grace period immediately after the deadline (say, one day). During the grace period, Alice would be unable to spend, but Bob could.

> **Comments:**
> **username_0**: Thank you very much! Nice thinking. However, it partially fixes my problem. If Bob disappears before the checklocktimeverify expires, and no results are published (no secret published) alice should be able to get only her bet back, e.g. 50% of the funds available in the p2sh address. How can this be achieved? Also, is there a limit of how many bits can the secret have? I would like to add like to add some random data to make brute force unworkable. Last but not least, is there some magic that Bob can do so the secret is published at some time regardless if he disappears?  

---

