forked from ethereum/EIPs
-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Create blockhash_refactoring.md (ethereum#210)
* Create blockhash_refactoring.md 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. * Update blockhash_refactoring.md * Update blockhash_refactoring.md * Update blockhash_refactoring.md * Update blockhash_refactoring.md * Update blockhash_refactoring.md * Update blockhash_refactoring.md * Update blockhash_refactoring.md * Update blockhash_refactoring.md * Update blockhash_refactoring.md * Update blockhash_refactoring.md * Rename blockhash_refactoring.md to eip-210.md
- Loading branch information
Showing
1 changed file
with
86 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
--- | ||
eip: 210 | ||
title: Blockhash refactoring | ||
author: Vitalik Buterin (@vbuterin) | ||
type: Standards Track | ||
category: core | ||
status: Draft | ||
created: 2017-02-10 | ||
--- | ||
|
||
### Summary | ||
|
||
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. | ||
|
||
### BLOCKHASH_CONTRACT_CODE | ||
|
||
The Serpent source code is: | ||
|
||
```python | ||
with offset = 0: | ||
if msg.sender == 0xfffffffffffffffffffffffffffffffffffffffe: | ||
with bn = block.number - 1: | ||
while 1: | ||
~sstore(offset + ~mod(bn, 256), ~calldataload(0)) | ||
if ~mod(bn, 256): | ||
~stop() | ||
bn = ~div(bn, 256) | ||
offset += 256 | ||
elif ~calldataload(0) < block.number: | ||
with tbn = ~calldataload(0): | ||
with dist_minus_one = block.number - tbn - 1: | ||
while dist_minus_one >= 256 && ~mod(tbn, 256) == 0: | ||
offset += 256 | ||
tbn = ~div(tbn, 256) | ||
dist_minus_one = ~div(dist_minus_one, 256) | ||
if dist_minus_one >= 256: | ||
return(0) | ||
return(~sload(offset + ~mod(tbn, 256))) | ||
else: | ||
return(0) | ||
``` | ||
|
||
The EVM init code is: | ||
|
||
``` | ||
0x6100e28061000e6000396100f056600073fffffffffffffffffffffffffffffffffffffffe33141561005957600143035b60011561005357600035610100820683015561010081061561004057005b6101008104905061010082019150610022565b506100e0565b4360003512156100d4576000356001814303035b61010081121515610085576000610100830614610088565b60005b156100a75761010083019250610100820491506101008104905061006d565b610100811215156100bd57600060a052602060a0f35b610100820683015460c052602060c0f350506100df565b600060e052602060e0f35b5b505b6000f3 | ||
``` | ||
|
||
The EVM bytecode that the contract code should be set to is: | ||
|
||
``` | ||
0x600073fffffffffffffffffffffffffffffffffffffffe33141561005957600143035b60011561005357600035610100820683015561010081061561004057005b6101008104905061010082019150610022565b506100e0565b4360003512156100d4576000356001814303035b61010081121515610085576000610100830614610088565b60005b156100a75761010083019250610100820491506101008104905061006d565b610100811215156100bd57600060a052602060a0f35b610100820683015460c052602060c0f350506100df565b600060e052602060e0f35b5b50 | ||
``` | ||
|
||
### Rationale | ||
|
||
This removes the need for implementaitons 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. |