Liar’s Dice sounds like a perfect game to put onchain.
The rules are simple, every move can be verified, and you don’t need a centralized game server deciding who won.
There is just one problem.
Blockchains are public. Liar’s Dice only works if your dice are private.
If I simply stored every roll inside a normal smart contract, anyone could inspect the state and know exactly what everyone was holding.
At that point, there is no bluffing.
You would basically be playing poker with everyone's cards face up.
So I built FHE Liar’s Dice, a decentralized version of the game where your dice remain encrypted while the game is being played.
Not hidden behind a backend.
Not stored privately in some database.
Encrypted onchain.
And the interesting part is that the smart contract can still use those encrypted dice to determine whether you are lying.
The problem with putting hidden-information games onchain
Most blockchain games actually benefit from transparency.
If you're building something like chess, every player is supposed to know the complete state of the board.
Liar’s Dice is different.
Each player starts with five dice that only they should be able to see.
Players then make public claims about the combined dice across the entire table.
You might say:
There are six 4s on the table.
The next player has two choices.
Raise the bid.
Or call your bluff.
The entire game comes from the fact that nobody knows exactly what everyone else is holding.
But a traditional smart contract has the opposite property.
Its state is transparent.
Even if the frontend refuses to display your dice, someone can simply inspect the contract, query the state, watch events, or build their own interface.
Hiding something in the UI isn't privacy.
I needed the actual game state itself to remain secret.
FHE turned out to be a very good fit for the game
I built the game using Fhenix CoFHE.
Fully Homomorphic Encryption is interesting because it allows computation to happen directly over encrypted values.
Normally encryption gives you privacy while data is stored, but you need to decrypt the data before doing anything useful with it.
With FHE, you can keep the value encrypted and still perform computations over it.
That completely changes what an onchain game can do.
In FHE Liar’s Dice, the contract generates each player's dice as encrypted values.
Conceptually, instead of the contract storing:
[2, 6, 4, 1, 3]
it stores encrypted representations of those values.
No plaintext die value is written into contract storage or emitted through an event while the round is active.
Only the player who owns that hand can unseal it and see what they rolled.
So your opponents can't read your dice.
An indexer can't read your dice.
And even the application operator doesn't get the plaintext values.
That gives the game something I couldn't get from a normal smart contract:
private state with public execution.
The weird part: checking a bluff without revealing the dice
This was the part I found most interesting while building the game.
Imagine I bid:
Six 4s.
Someone calls me a liar.
Now the contract needs to inspect every active player's dice and determine how many 4s actually exist.
In the version of Liar’s Dice I implemented, ones are wild, so they also count toward most bids.
The obvious implementation would be:
decrypt all dice
count the matches
compare count >= bid
But that defeats the entire point.
Instead, the contract performs the comparison over the encrypted values themselves.
It checks every encrypted die, calculates whether it matches the bid, includes wild ones where appropriate, and builds the result without revealing the underlying hands.
The final thing that needs to become public is essentially one bit of information:
Was the bid valid?
Yes or no.
If the true encrypted count meets the bid, the challenger loses.
If it doesn't, the bidder was lying and gets eliminated.
The actual count doesn't need to be revealed to reach that verdict.
That distinction is small, but it is the entire architecture of the game.
The chain gets enough information to enforce the rules without learning information it doesn't need.
What stays private and what stays public
I didn't want to make everything private.
That would remove one of the reasons to build the game onchain in the first place.
So I separated the game state into two categories.
Things like these are public:
- who joined the table
- turn order
- every bid
- who challenged
- whether the bid was valid
- who was eliminated
- the final result
The active dice are private.
That creates a nice split.
The strategy stays private. The execution stays verifiable.
After a challenge resolves, the hands from that round can be revealed so everyone at the table can see what actually happened.
Then the surviving players receive fresh encrypted hands for the next round.
The last player standing wins.
Why I didn't just use a server
The easy version of this project would have been straightforward.
Generate the dice on a backend.
Send each player their own hand.
Have the server determine whether every challenge succeeds.
From a game-development perspective, that works perfectly fine.
But then the server becomes the dealer, referee, and source of truth.
It knows everybody's dice.
It could theoretically alter rolls.
It could leak information.
And players ultimately have to trust whoever operates it.
That isn't particularly interesting to me.
The point of the experiment was to see whether we could remove that trusted game master without destroying the hidden-information mechanics that make Liar’s Dice fun.
FHE makes that possible.
The smart contract becomes the referee without becoming the omniscient dealer.
I also built a completely offline practice mode
One problem with building blockchain games is that people often need to connect a wallet before they even understand what the product does.
I didn't want that.
So FHE Liar’s Dice also has a practice mode.
It uses the same basic bluffing loop but runs locally against bots.
No wallet.
No blockchain transaction.
No encryption.
You can understand the game first, then enter the actual onchain lobby when you want to play the privacy-preserving version against other people.
The distinction is intentional.
There is no reason to pretend the offline version is decentralized.
It exists purely as an onboarding layer.
The game is still intentionally simple
The current version is a prototype.
There are no wagers.
No ranked mode.
No tournament system.
No timers.
I wanted to solve the harder primitive first:
Can you run an actual hidden-information bluffing game through a smart contract without exposing the hidden information?
Once that loop works, everything else becomes product design.
One known tradeoff in the current implementation is dice generation.
The dice are derived using an encrypted random uint8, reduced modulo six and shifted into the 1–6 range.
Because 256 isn't perfectly divisible by six, there is a very small distribution bias: faces 1 through 4 appear marginally more often than 5 and 6.
For a casual prototype I accepted that tradeoff and documented it rather than hiding it.
The contracts are also unaudited, so this is absolutely not something I would attach real-money wagering to in its current form.
What building this changed for me
Before this project, it was easy for me to think about blockchain privacy mostly in terms of private transfers or private financial positions.
Building a game made the idea much more tangible.
There is a huge class of applications where you don't necessarily need to hide the entire system.
You need to hide specific pieces of state while still allowing programs to compute over them.
Games are one example.
Auctions are another.
Voting, identity, trading strategies and many financial applications have variations of the same problem.
Public blockchains are extremely good at proving that computation happened according to known rules.
FHE adds another interesting possibility:
proving that rules were followed without forcing every input involved in those rules to become public.
Liar’s Dice happens to make that idea very easy to see.
You have five dice.
Nobody else should know them.
The contract still needs to know whether your bluff worked.
And somehow both things need to be true at the same time.
That is what I wanted to build.
Try bluffing against the blockchain
The project is live here:
https://fhe-liars-dice.vercel.app/
You can jump into practice mode without a wallet or create an onchain table and play the FHE version with other players.
The simplest description of the project is still probably the one I started with:
Nobody sees your dice.
Everyone sees your lies.
Top comments (0)