Feedback on the Guessing game

I implement a little guessing game; two players pick secret value’s and then take turns guessing the other’s secret. My implementation is here. I used an operator/referee who has knowledge of both secrets to advance play.

  1. Is there a way to avoid having a referee? I don’t think so (within the standard library provided features of the language), but I’m not sure.
  2. How idiomatic DAML is the code? Are there better patterns that I can use?
  3. There’s a scenario that demonstrates play, but unfortunately, the current implementation does not allow Alice to play against herself! That source of the error comes from a key uniqueness constraint, as the referee has to read the current state of play, archive it and create a new one within the same choice. I can work around this by passing a flipping Bool in the key logic but that’s ugly. Is there a better way?

Any other feedback would be great!

Leonid

1 Like

Regarding 1.) I haven’t tested any of this, but I think you can get rid of the referee role if you create one template containing the secret that only player A observes, one template announcing the new challenge to the other player containing a contract id of the secret contract. Then player B can create a template with its guess that both player A and B can see and that does contain a reference via a contract id to the secret, with a choice for player A to decide whether B guessed right or wrong. On a side note, this is an interesting example of how DAML divulges contract ids.

This would allow for asynchronous challenges/guesses, but you could order the players moves similar to what you did by having a template to create a new game with an identifier and only if you created the template you can create a new secret/challenge, or if you guessed for a challenge for a game.

1 Like

To prevent A from cheating one would add assert's into the choice’s body?

1 Like

Following up on @drsk’s suggestion I did implement an “operator”-less version of the game! It feels good to refine and find this boundary of DAML. To continue to probe, would it still be possible if the objective of the game was to guess something deterministic about both secrets, for example the GCD of the two secret numbers?

This guessing example, was an attempt at a reduction that lost that element. Specifically, I’m working on a Fog-of-war chess variation and in order to advance play I need to know both sides of the board. This is revealed to the referee. The problem described in question 3, is real, and aside from the flipping bool, I haven’t figured out a way to avoid the key conflict. In the operator-less version of the guessing game, there’s still a unique key constraint akin to 3. One can get around it via an extra intermediate contract, but that’s also inelegant; and also superfluous to logic of the game. I wonder if there is a different mechanism in the language that one can leverage when one wants to test that contracts that one signs with oneself have the same behavior as when you sign them with someone else. Is the resolution to just create a second Party to represent your “other” self?

1 Like

The code checking whether a guess is correct or not would be in DAML itself, so there’s no way someone could cheat. Also both parties will see the evaluation of that code. So you would add a Winner template, that can only be created via a choice when the code determined that someone guessed right.

1 Like

Running computations on secret input data without revealing it to the party carrying out the computation is generally a really hard problem (and also really interesting, check out zero knowledge proofs, and mpc). So in that case, I think the referee solution is best.

2 Likes

Thanks @drsk.

Excellent thread but moving to #general as this is discussing an entire project rather than a specific question so it fits better over there.

Another option for (1) which isn’t native DAML but more tied to implementation is using bots which run in TEEs, so you’re running with a “trusted” referee bot where the trust anchor is the trusted execution environment. You can see this as a hardware alternative to using ZKPs.

@soren is working on enabling a similar use case

1 Like

You may be interested in googling the word “mental poker”; per Wikipedia:

Mental poker is the common name for a set of cryptographic problems that concerns playing a fair game over distance without the need for a trusted third party.

The referee could be a trigger host running on a machine that has no other connectivity than the ledger, but both players still need to trust whoever runs that machine.

1 Like

Thanks for all the pointers. I do want to constrain myself to what’s possible within current DAML, so we’ll use an referee / operator when we have to act on two private states.

Is there any feedback on the other points? In point 3, I want to be able to write within an Update that I will archive and create a template with the same key.

1 Like