Stores blockhashes in the state, reducing the protocol complexity and the need for client implementation complexity in order to process the BLOCKHASH opcode. Also extends the range of how far back blockhash checking can go, with the side effect of creating direct links between blocks with very distant block numbers, facilitating much more efficient initial light client syncing.
Parameters
CONSTANTINOPLE_FORK_BLKNUM: TBD
SUPER_USER: 2**160 - 2
BLOCKHASH_CONTRACT_ADDR: 0xf0 (ie. 240)
BLOCKHASH_CONTRACT_CODE: see below
Specification
If block.number == CONSTANTINOPLE_FORK_BLKNUM, then when processing the block, before processing any transactions set the code of BLOCKHASH_CONTRACT_ADDR to BLOCKHASH_CONTRACT_CODE.
If block.number >= CONSTANTINOPLE_FORK_BLKNUM, then when processing a block, before processing any transactions execute a call with the parameters:
SENDER: SUPER_USER
GAS: 1000000
TO: BLOCKHASH_CONTRACT_ADDR
VALUE: 0
DATA: <32 bytes corresponding to the blockās prevhash>
If block.number >= CONSTANTINOPLE_FORK_BLKNUM + 256, then the BLOCKHASH opcode instead returns the result of executing a call (NOT a transaction) with the parameters:
SENDER: <account from which the opcode was called>
GAS: 1000000
TO: BLOCKHASH_CONTRACT_ADDR
VALUE: 0
DATA: 32 byte zero-byte-leftpadded integer representing the stack argument with which the opcode was called
Also, for blocks where block.number >= CONSTANTINOPLE_FORK_BLKNUM, the gas cost is increased from 20 to 800 to reflect the higher costs of processing the algorithm in the contract code.
This removes the need for implementations to have an explicit way to look into historical block hashes, simplifying the protocol definition and removing a large component of the āimplied stateā (information that is technically state but is not part of the state tree) and thereby making the protocol more āpureā. Additionally, it allows blocks to directly point to blocks far behind them, which enables extremely efficient and secure light client protocols.