Alert Source Discuss
🚧 Stagnant Standards Track: Core

EIP-210: 区块哈希重构

Authors Vitalik Buterin (@vbuterin)
Created 2017-02-10

摘要

将区块哈希存储在状态中,降低了协议的复杂性,并减少了客户端实现处理 BLOCKHASH 操作码的复杂性。同时扩展了区块哈希检查可以追溯的范围,其副作用是在区块编号相距很远的区块之间创建直接链接,从而促进了更高效的初始轻客户端同步。

参数

  • CONSTANTINOPLE_FORK_BLKNUM: 待定
  • SUPER_USER: 2**160 - 2
  • BLOCKHASH_CONTRACT_ADDR: 0xf0 (即 240)
  • BLOCKHASH_CONTRACT_CODE: 见下文

规范

如果 block.number == CONSTANTINOPLE_FORK_BLKNUM,那么在处理区块时,在处理任何交易之前,将 BLOCKHASH_CONTRACT_ADDR 的代码设置为 BLOCKHASH_CONTRACT_CODE。

如果 block.number >= CONSTANTINOPLE_FORK_BLKNUM,那么在处理一个区块时,在处理任何交易之前,执行一个带有以下参数的调用:

  • SENDER: SUPER_USER
  • GAS: 1000000
  • TO: BLOCKHASH_CONTRACT_ADDR
  • VALUE: 0
  • DATA: <对应于区块 prevhash 的 32 字节>

如果 block.number >= CONSTANTINOPLE_FORK_BLKNUM + 256,那么 BLOCKHASH 操作码将返回执行一个带有以下参数的调用(不是交易)的结果:

  • SENDER: <调用操作码的帐户>
  • GAS: 1000000
  • TO: BLOCKHASH_CONTRACT_ADDR
  • VALUE: 0
  • DATA: 32 字节的零字节左填充整数,表示调用操作码的堆栈参数

此外,对于 block.number >= CONSTANTINOPLE_FORK_BLKNUM 的区块,gas 成本从 20 增加到 800,以反映在合约代码中处理算法的更高成本。

BLOCKHASH_CONTRACT_CODE

Serpent 源代码是:

with offset = 0:
    if msg.sender == 0xfffffffffffffffffffffffffffffffffffffffe:
        with bn = block.number - 1:
            while bn:
                ~sstore(offset + ~mod(bn, 256), ~calldataload(0))
                if ~mod(bn, 256):
                    ~stop()
                bn = ~div(bn, 256)
                offset += 256
    elif ~calldataload(0) >= 0 and ~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)

EVM 初始化代码是:

0x6100f58061000e60003961010356600073fffffffffffffffffffffffffffffffffffffffe33141561005857600143035b801561005257600035610100820683015561010081061561003f57005b6101008104905061010082019150610022565b506100f3565b600060003512151561006e574360003512610071565b60005b156100e7576000356001814303035b6101008112151561009857600061010083061461009b565b60005b156100ba57610100830192506101008204915061010081049050610080565b610100811215156100d057600060a052602060a0f35b610100820683015460c052602060c0f350506100f2565b600060e052602060e0f35b5b505b6000f3

合约代码应设置为的 EVM 字节码是:

0x600073fffffffffffffffffffffffffffffffffffffffe33141561005857600143035b801561005257600035610100820683015561010081061561003f57005b6101008104905061010082019150610022565b506100f3565b600060003512151561006e574360003512610071565b60005b156100e7576000356001814303035b6101008112151561009857600061010083061461009b565b60005b156100ba57610100830192506101008204915061010081049050610080565b610100811215156100d057600060a052602060a0f35b610100820683015460c052602060c0f350506100f2565b600060e052602060e0f35b5b50

理由

这消除了实现需要一种明确的方式来查看历史区块哈希的需要,简化了协议定义,并消除了“隐含状态”(技术上是状态但不是状态树的一部分的信息)的一个重要组成部分,从而使协议更加“纯粹”。此外,它允许区块直接指向远在其后的区块,这使得极其高效和安全的轻客户端协议成为可能。

Citation

Please cite this document as:

Vitalik Buterin (@vbuterin), "EIP-210: 区块哈希重构 [DRAFT]," Ethereum Improvement Proposals, no. 210, February 2017. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-210.