One oracle:
Implement as a MIPS instruction?

InputOracle -- Preagreed upon inputs (TODO: replace with memory reads from given address range)
  $a0 = input choice
    0 -- BlockHash(n)
    1 -- Transactions(n+1)
    2 -- Coinbase(n+1)
    3 -- Uncles(n+1)
  $a1 = shift amount
  returns
  $v0 = inputs[$a0] >> $a1

This has been changed to an MMIO oracle
hash at 0x30001000 loads len at 0x31000000 and data at 0x31000004

PreimageOracle -- key value store
  $a0 = dword index in value
  $t0 = hash[31:0]
  $t1 = hash[63:32]
  $t2 = hash[95:64]
  $t3 = hash[127:96]
  $t4 = hash[159:128]
  $t5 = hash[191:160]
  $t6 = hash[223:192]
  $t7 = hash[255:224]
  returns
  $v0 = preimage[$t7...$t0] >> ($a0 * 32)

Program returns a hash in mem(0x30000800) and exits(jump to 0x5EAD0000) with the hash in the state

Challenge Flow:
C is challenger, D is defender
Super nice, the defender barely needs to spend gas!

C: InitiateChallenge(uint blockNumberN, bytes blockHeaderN, bytes blockHeaderNp1,
                     bytes32 assertionHash, bytes32 finalSystemHash, string[] assertionProof, uint256 stepCount)
  * checks hashes of the block headers
  * saves inputs for input oracle
  * confirms assertionHash != blockHeaderNp1.Hash
  * confirm assertionProof[0..7] proves the final state of [$t7...$t0] in finalSystemHash is assertionHash
  * confirm assertionProof[8] proves the final state of $pc in finalSystemHash is 0x5EAD0000
  * L = 0, R = stepCount   # we agree at L=0, we disagree at R=stepCount
  * return new challengeId
  * assertedState[0] = GlobalStartSystemHash + inputOracleMutations
  * defendedState[0] = GlobalStartSystemHash + inputOracleMutations
  * assertedState[stepCount] = finalSystemHash
........
if it's one step, we are done. considering it's not, we binary search
........
C: ProposeState(uint256 challengeId, uint256 riscState)
  * stepNumber = GetStepNumber(uint256 challengeId) returns floor((L + R) / 2)
  * assert assertedState[stepNumber] == 0
  * assertedState[stepNumber] = riscState
D: RespondState(uint256 challengeId, uint256 riscState) onlyOwner
  * off-chain: run to step = stepNumber, get state hash, check if it matches
  * stepNumber = GetStepNumber(uint256 challengeId) returns floor((L + R) / 2)
  * defendedState[stepNumber] = riscState
  * if assertedState[stepNumber] == defendedState[stepNumber]:
      L = stepNumber     # we agree at stepNumber
    else:
      R = stepNumber     # we disagree at stepNumber
    # issue is between [L...R]
........
binary search until L+1 == R
the issue is with the L->R transition
aka assertedState[L] -> assertedState[R]
........
# call this at any time (global), adds them to a preimage lookup for PreimageOracle
# put these on the MIPS contract
C: AddPreimage(bytes anything)
  * preimageLookup[keccak256(anything)] = anything
C: AddMerkleState(uint256 stateHash, uint32 addr, uint32 value, string proof)
  * validate proof in assertedState[stepNumber]
  * riscMemory[stepNumber][address] = value

* Final
C: ConfirmStateTransition(uint256 challengeId)
  * assert L+1 == R
  * do the state transition
  * if any needed pieces of start state are missing in riscMemory, challenge fails (it can try again)
  * reconstruct the riscState after transition -> newState 
  * assert assertedState[R] == newState
  * pay out bounty

# optional claim for the defender
# prove the defendedState[L] -> defendedState[R]
# NOTE, if it's the last step, defendedState[R] might not exist. 

TODO: ensure the state merklization is canonical. if it doesn't match perfectly you can lose