Skip to main content

Understanding On-Chain Randomness

Before diving into code, let's understand why traditional randomness approaches fail on blockchains and how NEAR solves this problem.

Why Traditional Methods Don't Work

// Using timestamp - Predictable and manipulable
const outcome = Date.now() % 2 ? 'heads' : 'tails';

// Using block data - Miners can influence
const result = block.timestamp % 100;

// Using previous transaction - Public and predictable
const random = previousTx.hash % 6 + 1;

NEAR's VRF Solution

NEAR uses a Verifiable Random Function (VRF) that provides:

The random seed is:

  • Unpredictable: Cannot be known before the block is produced
  • Verifiable: Can be cryptographically verified as authentic
  • Consistent: Same for all transactions in a block

Accessing Randomness in Your Contract

Important Limitations

Block-Level Consistency

All calls to random_seed() within the same block return the same value:

// Both calls return the same seed if in the same block
const seed1 = near.randomSeed();
const seed2 = near.randomSeed();
// seed1 === seed2

Generating Multiple Values

To get different random values in one transaction, combine the seed with unique data:

// To get different random values in one transaction
function multipleRandomValues(count) {
const seed = near.randomSeed();
const values = [];

for (let i = 0; i < count; i++) {
// Mix seed with index for uniqueness
const mixed = new Uint8Array([...seed, i]);
values.push(mixed[0] % 100);
}

return values;
}

Security Considerations

warning

NEAR's randomness is suitable for:

  • ✅ Games and lotteries
  • ✅ NFT trait generation
  • ✅ Random selection processes

But NOT for:

  • ❌ Cryptographic key generation
  • ❌ Security-critical random values
  • ❌ High-value financial applications without additional safeguards

Now that you understand the fundamentals, let's build a coin flip contract that properly uses NEAR's randomness.