Update blockhash_refactoring.md

This commit is contained in:
vbuterin 2017-04-26 05:04:58 -04:00 committed by GitHub
parent 600b28fb1c
commit cebb3e220c

View File

@ -23,7 +23,7 @@ Stores blockhashes in the state, reducing the protocol complexity and the need f
If `block.number == METROPOLIS_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 >= METROPOLIS_FORK_BLKNUM`, then when processing a block, before processing any transactions execute a call with the parameters:
If `block.number >= METROPOLIS_FORK_BLKNUM + 256`, then when processing a block, before processing any transactions execute a call with the parameters:
* `SENDER`: SUPER_USER
* `GAS`: 1000000
@ -39,32 +39,44 @@ If `block.number >= METROPOLIS_FORK_BLKNUM + 256`, then the BLOCKHASH opcode ins
* `VALUE`: 0
* `DATA`: 32 byte zero-byte-leftpadded integer representing the stack argument with which the opcode was called
Also, the gas cost is increased from 20 to 350 to reflect the higher costs of processing the algorithm in the contract code.
Also, the gas cost is increased from 20 to 800 to reflect the higher costs of processing the algorithm in the contract code.
### BLOCKHASH_CONTRACT_CODE
BLOCKHASH_CONTRACT_CODE is set to the compile output of the following Serpent code:
BLOCKHASH_CONTRACT_CODE is set to:
```
0x73fffffffffffffffffffffffffffffffffffffffe33141561006a5760014303600035610100820755610100810715156100455760003561010061010083050761010001555b6201000081071515610064576000356101006201000083050761020001555b50610146565b4360003512151561008457600060405260206040f3610145565b61010060003543031315156100a857610100600035075460605260206060f3610144565b6101006000350715156100c55762010000600035430313156100c8565b60005b156100ea576101006101006000350507610100015460805260206080f3610143565b620100006000350715156101095763010000006000354303131561010c565b60005b1561012f57610100620100006000350507610200015460a052602060a0f3610142565b6000610100600035071460c052602060c0f35b5b5b5b5b
```
The Serpent source code is:
```python
if msg.sender == {SUPERUSER}:
prevblock_number = block.number - 1
~sstore(prevblock_number % 256, ~calldataload(0))
if prevblock_number % 256 == 0:
~sstore(256 + (prevblock_number / 256) % 256, ~calldataload(0))
if prevblock_number % 65536 == 0:
~sstore(512 + (prevblock_number / 65536) % 256, ~calldataload(0))
# Setting the block hash
if msg.sender == 2**160 - 2:
with prev_block_number = block.number - 1:
# Use storage fields 0..255 to store the last 256 hashes
~sstore(prev_block_number % 256, ~calldataload(0))
# Use storage fields 256..511 to store the hashes of the last 256
# blocks with block.number % 256 == 0
if not (prev_block_number % 256):
~sstore(256 + (prev_block_number / 256) % 256, ~calldataload(0))
# Use storage fields 512..767 to store the hashes of the last 256
# blocks with block.number % 65536 == 0
if not (prev_block_number % 65536):
~sstore(512 + (prev_block_number / 65536) % 256, ~calldataload(0))
# Getting the block hash
else:
if ~calldataload(0) >= block.number or ~calldataload(0) < {METROPOLIS_FORK_BLKNUM}:
return 0
if block.number - ~calldataload(0) >= 256:
return ~sload(~calldataload(0) % 256)
elif block.number - ~calldataload(0) >= 65536 and ~calldataload(0) % 256 == 0:
return ~sload(256 + (~calldataload(0) / 256) % 256)
elif block.number - ~calldataload(0) >= 16777216 and ~calldataload(0) % 65536 == 0:
return ~sload(512 + (~calldataload(0) / 65536) % 256)
if ~calldataload(0) >= block.number:
return(0)
elif block.number - ~calldataload(0) <= 256:
return(~sload(~calldataload(0) % 256))
elif (not (~calldataload(0) % 256) and block.number - ~calldataload(0) <= 65536):
return(~sload(256 + (~calldataload(0) / 256) % 256))
elif (not (~calldataload(0) % 65536) and block.number - ~calldataload(0) <= 16777216):
return(~sload(512 + (~calldataload(0) / 65536) % 256))
else:
return 0
return(~calldataload(0) % 256 == 0)
```
### Rationale