From cebb3e220c62b9fbe896b474391c3e26c380082c Mon Sep 17 00:00:00 2001 From: vbuterin Date: Wed, 26 Apr 2017 05:04:58 -0400 Subject: [PATCH] Update blockhash_refactoring.md --- EIPS/blockhash_refactoring.md | 52 +++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/EIPS/blockhash_refactoring.md b/EIPS/blockhash_refactoring.md index eb7a25ed..6e902fdf 100644 --- a/EIPS/blockhash_refactoring.md +++ b/EIPS/blockhash_refactoring.md @@ -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