Skip to main content

Randomness and VRF

Gora produces randomness as a side effect of how committees are selected. Every consensus round already involves each validator publishing a verifiable random output. Your app or your on-chain contract can request that randomness, bound to a specific request, and verify it later.

What VRF means here

A verifiable random function (VRF) is a sealed envelope:
  • The validator computes the envelope with their private key.
  • The envelope looks random to everyone else.
  • Anyone with the validator’s public key can verify the envelope is genuine.
  • The envelope is decided before the round starts — no one can pick a different number after seeing how it played out.
The Gora VRF uses ed25519 signatures plus SHA-256. Output is 32 bytes; proof is 64 bytes. Both are deterministic given (participation_key, input).

Two ways to access VRF

SurfaceUse it whenHow
Off-chain appYou need randomness inside your app logic (e.g. a raffle winner).Read request.vrf provided by the runtime.
On-chain contractA smart contract needs unpredictable randomness it can verify.Call Gora through the chain’s gateway program; verify the VRF proof in your contract.
Both use the same VRF — they just consume it from different sides.

From an off-chain app

Every Gora app invocation arrives with a vrf field on the request. It is derived from the proposer’s VRF output for that round, domain-separated by request_id so the same app on different requests sees different randomness.
// src/index.ts
export async function run(req: GoraRequest): Promise<GoraResult> {
  const entrants: string[] = req.input.participants;
  const vrf = req.vrf;                       // { output_hex, proof_hex }

  // Map the 32-byte VRF output to an index, deterministically.
  const indexBigInt = BigInt("0x" + vrf.output_hex.slice(0, 16));
  const winnerIndex = Number(indexBigInt % BigInt(entrants.length));

  return {
    type: "raffle_result",
    schema_version: 1,
    app_id: req.app_id,
    decision: "winner_selected",
    payload: {
      winner: entrants[winnerIndex],
      vrf_output_hex: vrf.output_hex,        // for receipts / on-chain verification
    },
  };
}
Because the VRF is part of the round’s published context, every committee member computes the same winnerIndex from the same vrf.output_hex. The result is reproducible at verification time.

From a smart contract

A smart contract requests randomness by calling the Gora gateway on its chain. The gateway routes the request to Gora, the committee runs the request, and the gateway delivers a callback to the contract with { result, vrf_output, vrf_proof, signatures }.
// Solidity sketch — Base
interface IGoraGateway {
    function requestRandomness(bytes calldata seed) external returns (bytes32 requestId);
}

interface IGoraConsumer {
    function fulfillRandomness(
        bytes32 requestId,
        bytes32 vrfOutput,
        bytes calldata vrfProof,
        bytes[] calldata signatures
    ) external;
}
When the callback lands, your contract:
  1. Verifies the committee signatures against the registered validator set.
  2. (Optional) Verifies the VRF proof against the committee proposer’s pubkey using a Solana-style precompile or an EVM ed25519 verifier.
  3. Uses vrfOutput as randomness.
The same pattern applies on Solana (instruction-based callback) and Algorand (atomic-group fulfillment). The exact gateway interfaces ship with the chain contracts in contracts/.

What makes this safe

PropertyWhy it holds
UnpredictabilityThe VRF input includes request_id and the round’s sequence; the participation key never leaves the validator.
VerifiabilityAnyone with the proposer’s public key can check the proof.
Tamper-evidenceThe output is committed to before votes are signed; changing it later invalidates the entire round attestation.
Bias resistanceThe proposer is chosen by stake-weighted VRF score over the collected submissions, not by a single validator’s whim.

When not to use Gora VRF

  • You need millions of independent draws per second on-chain. Gora is request-scoped, not a high-throughput randomness firehose.
  • You only need a hash of the recent block. The chain’s own block hash is cheaper and sufficient for low-stakes randomness.
For everything between “trust me, it’s random” and “I need a national lottery RNG,” Gora VRF is the intended fit.