DEV Community

Manav
Manav

Posted on

The RNG Problem on Chain Is Real: Here's How Oasis Tackles It Differently

Onchain Randomness

If you've ever tried to build anything onchain that needs randomness, real randomness, not blockhash spaghetti you know how painful it is.

Gaming? Lotteries? NFT minting? Even something as basic as randomized token IDs gets tricky fast. Because here’s the truth: blockchains aren't built for randomness. They're built for determinism and consensus. And those two don’t exactly play nice with entropy.

So what do most devs do? They hack around it:

  • Use blockhashes (predictable)
  • Do commit-reveal (delay-heavy, gameable)
  • Call Chainlink VRF (offchain dependency, gas cost, complexity)

But then I ran into something different: Oasis’s take on randomness. Not just how they do it (with TEEs and VRFs), but where they integrated it—deep into the Sapphire confidential EVM runtime.

Let’s break it down.

🧠 TL;DR: They Built a TEE-Powered, Ephemeral-Key, Domain-Separated RNG Engine

That’s a mouthful. Here's the gist.

Oasis uses trusted execution environments (TEEs) to do something most chains can’t: generate and preserve entropy that isn’t visible to the world, but still usable from contracts.

They exposed this through a precompile in Sapphire called randomBytes. So from Solidity, randomness looks like this:

bytes memory rand = Sapphire.randomBytes(32, "");
Enter fullscreen mode Exit fullscreen mode

But behind that one-liner is a pretty clever setup involving:

  • Per-epoch ephemeral keys that self-destruct
  • Merlin transcripts for domain-separated RNG instances
  • VRFs for verifiability
  • cSHAKE + TupleHash + KMAC256 as building blocks
  • And no guessable state ever leaves the enclave

Let’s unpack this from a builder’s POV.

🚧 The Problem: Why Can't We Just rand()?

Simple: every node has to reach the same result. And if anyone can influence or predict your randomness, they can game your logic.

That’s why commit-reveal exists. That’s why Chainlink VRF exists. But both come with tradeoffs—delays, external calls, or attack surfaces.

Oasis flips the model by using enclaves (Intel SGX) that:

  • Hold private state per node
  • Are attested (you can verify they’re legit)
  • Can seal entropy so no one—not even the dev—can peek

So every Sapphire node has access to secure, unguessable entropy… that’s never leaked.

🔐 How the RNG Pipeline Actually Works

1. Entropy Generation (Per Epoch)

Each node's enclave talks to a trusted key manager. It gets:

  • Long-term keys (for general TEE ops)
  • Ephemeral keys (rotated every epoch)

These ephemeral keys are memory-only and are never stored. Think of them like single-use key material that powers everything for that epoch—then disappears forever.

If someone breaks the system later, they still can’t rewind history and learn anything.

2. Per-Block Root RNG

For each new block:

  • The enclave uses the current epoch’s ephemeral entropy
  • Runs it through cSHAKE/TupleHash/KMAC to derive a VRF seed
  • That becomes the block-root RNG

Now you’ve got one fresh root of trust per block. And it never leaves the enclave.

3. Per-Transaction Domain Separation

Every tx needs its own randomness. So Sapphire applies domain separation using Merlin transcripts—a clean cryptographic way to customize randomness by context.

The runtime mixes in:

  • The root RNG
  • Tx sender
  • Tx hash
  • Whatever else it needs

Result: each tx gets its own RNG stream. No collisions, no shared state, no leaks.

📦 For Devs: You Get a Simple Precompile

You don’t have to implement any of this. You just call:

bytes memory rand = Sapphire.randomBytes(32, "");
Enter fullscreen mode Exit fullscreen mode

Or if you need randomness for key generation:

(pk, sk) = Sapphire.generateSigningKeyPair(
  Sapphire.SigningAlg.Ed25519Pure,
  Sapphire.randomBytes(32, "")
);
Enter fullscreen mode Exit fullscreen mode

The SDK handles everything. You don’t deal with transcripts, entropy, or cryptographic weirdness.

🛠️ Use Cases That Actually Work Now

This isn't theoretical. Here’s where it shines:

  • 🎲 Provably fair games — No one can precompute moves. Combat logic, loot drops, card deals—all hidden until used.
  • 🧬 Unique NFTs — No duplicate mints, no race conditions.
  • 🎟️ Private lottery selection — Draw winners in a single tx. No commit-reveal mess.
  • 🗳️ Confidential DAO voting — Use randomness to assign jury duty-style committees or proposals.

Basically: if your app depends on randomness and you want it verifiable, private, and fast, this is worth a look.

Try It Yourself

Here’s everything you need to mess with it:

No setup required beyond deploying to Sapphire. The precompile works out of the box.

🧵 Final Thoughts

I’ve seen this on Ethereum, Arbitrum, Optimism, Filecoin and all of them struggle with the same thing: randomness that isn’t terrible.

What Oasis did here is different. They didn’t patch over the RNG problem. They re-architected it inside the TEE. That unlocks stuff other chains just… can’t do yet.

And yeah, it’s a niche stack. But if you're building anything where fairness, secrecy, or unpredictability matter? Don’t sleep on this.

Let me know if you’re experimenting with it or hit me up if you want help plugging it into your app.

Let’s make randomness suck less, one TEE at a time.

Top comments (1)

Collapse
 
dc600 profile image
DC

An excellent read. RNG is always a challenge, even for web2 games. With blockchain's innate transparency, web3 games were having a troubled time incorporating this aspect. Until Oasis approached and revolutionized on-chain randomness with TEEs and the ROFL framework. I am anticipating a quantum leap in the development of web3 gaming and the metaverse in the days to come.
For example, MonCraft is one of the winners in the recent ETHDam hackathon, and they implemented secure randomness and privacy features for a fair gaming experience (a demo: taikai.network/cryptocanal/hackath...).