DOOMON ROBINHOOD CHAINSEALED · OWNERLESS

DOOM is a
contract now

The whole 1993 shareware game lives in the bytecode of 24 contracts on Robinhood Chain, with a 25th holding the code that starts it. Your browser reads all of it from the chain and runs it. No server of ours holds the game — this page is a folder of static files, and every byte of DOOM comes from a node you can point elsewhere.

Contract addressNot launched yet
2,241,676bytes, on chain, in state
24contracts holding the game
11,101,925gas for the chain to check it
0servers of ours between you and E1M1

Robinhood Chain stores 98,304 bytes in a contract, four times Ethereum’s limit. A shard is 93,405, because a payload has to be sent before it can be stored and the sequencer takes 95,000 bytes of calldata per transaction. The first deploy found that out at shard 0.

Pull it from the chain

Every byte comes out of contract bytecode, one eth_getCode at a time. Slower than a CDN. That is the point.

Check it yourself
shards read
0%of the game
registry
  • Checked against a digest compiled into this page and published before this chain existed. No endpoint can fake these.
  • the bytes are the DOOM build published before this chain existed — not checked yet
  • the boot code, the only JavaScript that runs, is the published build — not checked yet
  • Computed here, but self-consistency only — the endpoint supplies both sides.
  • every shard sits at the address its own bytes derive — not checked yet
  • the bytes match the hash it declares for them — not checked yet
  • Taken from the endpoint. True if it is honest.
  • it reports Robinhood Chain (4663) — not checked yet
  • it reports the registry as sealed — not checked yet
  • it reports no owner — not checked yet
  • its own on-chain verify returned true — not checked yet

Reading from Any Robinhood Chain node will do. The checks do not change.

Anyone can put a file on a blockchain.

We made the blockchain check it.

This one hands you a transaction in which the EVM itself reassembled all 2,241,676 bytes, hashed them, and agreed. Don’t trust us — you can’t, really, and that’s the feature. Three ways to check. The first is the one a hostile node cannot get past; the other two show you how it fits together.

1

Hash it yourself

Pull each shard with eth_getCode, drop the first byte of every one — the STOP that keeps a shard from ever executing — concatenate the rest, and SHA-256 it. It matches the hash the registry declares, and the digest this page was built with — published before this chain held a single byte of the game. The second comparison is the one that matters: a registry that declares the hash of whatever it happens to hold agrees with itself perfectly.

python3 tools/verify-onchain.py 0x2EC1e6c9c43b9E62218b31826cE7db2fe1699Cdc --rpc https://rpc.mainnet.chain.robinhood.com

No dependencies, no web3 library, its own keccak-256. It also refuses a registry that is unsealed, still owned, or missing the game.

2

The address is the hash

Every shard was deployed through the canonical CREATE2 proxy at a fixed zero salt, so its address is derived from its own bytecode. Recompute it from the bytes you were served and it matches where they came from. Flip one byte and the address moves, so nothing can sit at a shard’s address but that shard’s exact bytes. This one is self-consistency, not identity: the address list and the bytecode come from the same node, so a dishonest one can satisfy it by picking addresses that derive from its own bytes. It is level 1 that stops that, and level 1 is where the argument actually rests.

Read shard 0 from Robinhood Chain and derive its address here, in this tab, from the bytes alone.

the derivation, in full
initCode = 0x600b5981380380925939f300…  (prefix ‖ STOP ‖ payload)
address  = keccak256(0xff ‖ 0x4e59…4956C ‖ 0x00…00 ‖ keccak256(initCode))[12:]
3

The chain already did it

attest() re-runs the whole reassembly and hash as a transaction, inside the EVM, and leaves a receipt in the log. Measured: 11,105,994 gas, roughly two dollars. It is permissionless, so you can make another one whenever you like — and verify() is the same check as a free call, at 11,101,925 gas.

The registry on Blockscout — read verify there yourself, or send attest and leave your own receipt.

Putting a file in transaction history gets you the first one and neither of the others. Nothing on chain can read transaction history from inside a contract, so nothing on chain can check it. Runtime code can be read, which is the whole reason the game is stored as code.

Bytes as bytecode

A contract’s runtime code is just bytes in the state trie. Put a STOP at the front — call it and it halts before reaching your data — and the rest is storage that every full node carries, that costs no rent, and that another contract can read with EXTCODECOPY.

EIP-170 caps that at 24,576 bytes on Ethereum. Robinhood Chain allows 98,304, four times as much. Neither number is what sets a shard: the chain has to accept the payload before it can store it, and its sequencer takes 95,000 bytes of calldata in a transaction. That is the smaller limit, so a shard is 93,405 bytes and 2.24 MB takes 24 contracts.

Each one deploys in a single transaction, and the reassembly of all 24 is re-hashed inside one more — under this chain’s 32,000,000 gas ceiling per transaction, with room to spare but not much.

The registry is sealed and ownerless. Sealing is not a formality: it only succeeds if the EVM reassembles every asset from chain state and gets the declared hash, so a sealed registry is a statement the chain checked rather than one we made. There is no upgrade function, because a DOOM you could swap out later would not be worth looking at.

Questions

Is this actually DOOM?
It’s linuxdoom-1.10 compiled to WebAssembly with the shareware WAD linked in. Episode 1, Knee-Deep in the Dead. Nine levels, including the one with the invisible pinkies.
Why is loading slow?
Because it is reading 2.2 MB out of contract bytecode instead of a CDN, one eth_getCode at a time. We could cache it in your browser and we deliberately don’t: every load should cost what the claim costs, or the claim means nothing.
Can you take it down?
No. The registry has no owner; sealing cleared it. We can turn this website off. The game stays.
What if this website disappears?
The bytes don’t. The verification script has no dependencies and implements its own keccak — it is one file, and it will still work. That is the whole point of writing it down.
Did you pay id Software?
The shareware episode has been freely redistributable since 1993. That was the deal then and it is the deal now.
Is there a token?
Not yet. If there is one, it will do nothing to the game: the game won’t know it exists and the contracts won’t reference it. That’s the honest way round, and it is also the arrangement that survives a token going to zero.