EIP210 - 重组区块哈希在以太坊网络上的存储方式

# 摘要

将区块哈希存储在状态中,从而降低协议复杂性和处理区块哈希操作码所需的客户端实现复杂性。它还扩展了区块哈希检查的范围,其副作用(side effect)是在具有非常远的区块编号的区块之间创建直接链接,从而促进更高效的初始轻客户端同步。

# 参数

  • CONSTANTINOPLE_FORK_BLKNUM: TBD
  • SUPER_USER: 2**160 - 2
  • BLOCKHASH_CONTRACT_ADDR: 0xf0 (ie. 240)
  • BLOCKHASH_CONTRACT_CODE: see below

# 规格参数

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:
  • 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

另外,对于 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)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

EVM初始化代码是:

0x6100f58061000e60003961010356600073fffffffffffffffffffffffffffffffffffffffe33141561005857600143035b801561005257600035610100820683015561010081061561003f57005b6101008104905061010082019150610022565b506100f3565b600060003512151561006e574360003512610071565b60005b156100e7576000356001814303035b6101008112151561009857600061010083061461009b565b60005b156100ba57610100830192506101008204915061010081049050610080565b610100811215156100d057600060a052602060a0f35b610100820683015460c052602060c0f350506100f2565b600060e052602060e0f35b5b505b6000f3
1

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

0x600073fffffffffffffffffffffffffffffffffffffffe33141561005857600143035b801561005257600035610100820683015561010081061561003f57005b6101008104905061010082019150610022565b506100f3565b600060003512151561006e574360003512610071565b60005b156100e7576000356001814303035b6101008112151561009857600061010083061461009b565b60005b156100ba57610100830192506101008204915061010081049050610080565b610100811215156100d057600060a052602060a0f35b610100820683015460c052602060c0f350506100f2565b600060e052602060e0f35b5b50
1

# 逻辑依据

不需要实现以明确的方式查看历史区块哈希值,简化协议定义并删除“隐含状态”(技术上是状态,但不是状态树的一部分的信息)的一大部分,从而使协议更“纯粹”。此外,它允许块直接指向它们后面很远的块,从而实现极其高效和安全的轻客户端协议。

▲ Powered by Vercel