Event and player IDs
Props Oracle uses two deterministic identifiers that a consumer can compute independently. Both are bytes32 values produced by keccak256 over public, immutable inputs. Recomputing them locally is the primary way a consumer verifies that an assertion refers to the event or player they expect.
Canonical event ID
The canonical event ID identifies a specific scheduled game across any oracle stream that references it. It is defined as:
bytes32 canonicalEventId = keccak256(abi.encodePacked(
leagueCode,
homeTeam,
awayTeam,
commenceTime
));All four inputs must match the canonical values the oracle uses. The league code is the lowercase short code ("mlb", "nba", "nfl"). The team strings are the canonical names published in the per-league reference — not the odds-provider names, not the stats-provider names, not a jersey city, but the exact string the oracle hashes. The commence time is the unix timestamp of the scheduled first pitch, tip-off, or kickoff, as stored in the schedule the oracle ingests.
Getting any input wrong — a typo in a team name, a different time zone, a league code with different casing — produces a different hash and no registry hit. This is by design. The ID is strict because it has to correlate assertions across independently operated oracle streams without coordination.
Oracle player ID
The oracle player ID is a stable identity for a single athlete across their career. It is computed once at creation time and never changes, even after trades, jersey number changes, or legal name changes:
bytes32 oraclePlayerId = keccak256(abi.encodePacked(
sportKey,
fullName,
jerseyNumberAtCreation
));The jersey number in the hash is the number the player held when the record was first created, not their current number. It serves only to disambiguate name collisions at creation time — two active players named "Josh Allen" in the NFL, for example, hash to different IDs because they had different jersey numbers when they were first added. Once minted, that disambiguator is frozen.
When a player has no jersey number available at creation (preseason, unrostered free agent, draft pick), the fallback value "P0" is used. This is rare and affects only the initial few days of a player's record before rosters are finalized.
All three inputs are public. Any party can recompute an oracle_player_id for a current roster player by looking up their sport, canonical name, and creation-era jersey number. The oracle publishes a mapping table from oracle_player_id back to human-readable metadata, but the contract-level identity is always the hash.
Why deterministic derivation matters
Deterministic identifiers let a consumer contract verify oracle output without trusting any off-chain process. A market written against "Aaron Judge over 1.5 hits on April 22" can, in the same transaction that pays out, recompute both the event ID and the player ID from values it locked in at market creation, and confirm they match what is in the assertion. This is a stronger guarantee than trusting a string lookup, and it makes disputes cheaper because disputers can audit the same derivation.