HashX

Oct 20254 min read

Privacy-preserving prediction markets on Hedera, with encrypted voting, timelock-based resolution, and Merkle-proof rewards.

Next.jsTypeScriptHederaSolidityPostgreSQL

An oracle for events beyond the blockchain

HashX was built for ETHOnline 2025 around a practical question: how can a prediction market settle an event whose answer lives outside the blockchain? The project combines an optimistic oracle with a prediction-market application on Hedera EVM. Users create questions, define resolution criteria, fund markets, and participate in the process that determines the outcome.

The architecture separates the oracle from the market that uses its result. An oracle manages voting, the resolution key, and voter rewards. A linked prediction-market contract manages outcome tokens and collateral. This makes the path from collecting an answer to settling a market explicit, with each contract responsible for a different part of the lifecycle.

From wallet connection to an encrypted ballot

The application uses RainbowKit and wagmi for wallet connectivity, with viem handling contract interactions. Participants stake HBAR through the locking contract, which provides wrapped HBAR for the voting flow. Before accepting a vote, the oracle checks the voting window, the participant’s available deposit, and whether that address has already voted.

A vote begins with an EIP-712 typed signature describing the market, option, and amount. The verification action binds that message to its chain and contract. A server action combines the signature with fresh randomness to derive an ephemeral BabyJubJub key. Elliptic-curve Diffie–Hellman produces the shared secret used to encrypt the chosen option with AES-256-CTR.

  • The contract records the encrypted ballot, the voter’s public key, and the deposited amount.
  • VoteCast events give the resolution workflow the data it needs to reconstruct the ballot set.
  • Vote counts are calculated per participant; reward allocation uses the winning participants’ deposited amounts.

Making the resolution key available through work

Oracle creation generates a key pair and a timelock puzzle. The puzzle builder creates a 4096-bit RSA modulus, calculates a repeated-squaring result, hashes that result into a mask, and uses the mask to lock the secret key. The public parameters include the modulus, base, iteration count, and locked secret.

A solver can use those parameters to perform the sequential computation and recover the key. The contract checks the recovered secret against its stored commitment and records the solver. The application also supports an automatic mode that retains the key server-side. The configured iteration count controls computational work, while contract timestamps govern when voting is open.

Turning revealed votes into a settled market

After voting closes, the resolution workflow uses the recovered key and each voter’s public key to derive the corresponding shared secret and decrypt the ballot. The application tallies the two options and prepares the result for finalization. The oracle owner submits the counts and winner commitment after the voting deadline.

Finalization reports the outcome to the linked prediction market. Its reporting function accepts that result from the configured oracle, connecting the two contracts. The market contracts also include outcome-token purchases and sales, liquidity management, and redemption of winning tokens, so resolving the question feeds into an actual settlement flow.

Proof-based reward claims

The application builds an OpenZeppelin StandardMerkleTree from voter addresses and deposited amounts. It stores a compact winner root on-chain and saves the individual proofs in PostgreSQL. A winning participant can fetch their proof and submit a claim against the oracle contract.

The claim function reconstructs the participant’s leaf, verifies it against the stored root, and calculates the deposited amount plus that participant’s share of the reward pool. It clears the deposit before transferring funds. This keeps the on-chain commitment compact while allowing claims to happen individually.

Keeping the app, database, and contracts in step

The frontend is built with Next.js, React, TypeScript, Zustand, and TanStack Query. Drizzle and PostgreSQL hold market metadata, oracle configuration, puzzle parameters, resolution state, and claim proofs. Those records let the interface present a usable market directory around the underlying contracts.

The division of work is deliberate: wallet interactions and settlement live around the contracts, while encryption actions, tally preparation, and proof generation run in the application layer. The prototype makes those boundaries visible through separate creation, voting, verification, and claiming steps, with source-level helpers for testing the puzzle-solving path.