Ethereum Eth2 deposit merkle tree

1 Introduction

Ethereum 2.0 (Eth2) adopts the sharded PoS protocol, in an early stage (named Phase 0), running in parallel with the existing PoW chain (named Eth1 chain). Eth1 is powered by miners, while PoS chains (aka Beacon chains) are powered by validators.

In the Beacon chain, the validator role is responsible for:

  • 1) Create (Propose) a new block
  • 2) Attest the new block

The consensus protocol in the Beacon chain is mainly based on the following important gadgets:

The above consensus protocol guarantees safety and liveness when the majority of validators are loyal.

The validator set is dynamic, which means that new validators can be added at any time, and old validators can also be withdrawn. For the new validator, it needs to deposit a certain amount of Ether as a stake, and send a transaction to a specific contract (named deposit contract) through the Eth1 network. All deposit history is recorded in the deposit contract, from which the Beacon chain can retrieve data to maintain its dynamic validator set. (Although the corresponding deposit process will be modified later.)

The relevant codes are:

Merkle tree related blogs are:

2. Deposit contract

insert image description here
In the deposit contract written in the Vyper language , the Mekrle tree data structure is introduced to efficiently store the deposit history. When a new deposit is received, the Merkle tree is dynamically updated (that is, the leaf nodes are increased sequentially from left to right) .

The merkle tree height in the current deposit contract is 32, and it supports storing up to 2 32 2^{32}23 2 deposits. Since the merkle tree is very large, when there is a new deposit, the whole tree is not displayed every time when the whole tree is rebuilt.

In order to reduce the required time and space and thus introduce gas cost, the deposit contract adopts the incremental Merkle tree algorithm . The incremental algorithm requires only O ( h ) O(h)O ( h ) space-time complexity to reconstruct (accurately calculate the root of) a Merkle tree of heighthhh , while the intuitive algorithm requiresO ( 2 h ) O(2^h)The ( 2h )time or space complexity. The incremental algorithm maintains 2 lengths ofhhThe array of h , each time an updated tree is reconstructed, only a chain starting from the new leaf (ie the new deposit) to the root needs to be calculated, and the calculation method of the chain only needs 2 arrays, so as to achieve the same value as the tree height. Time and space complexity of a linear relationship.

Runtime verification found a bug. If all leaves are filled, the merkle root calculation is wrong. For details, see:

For a merkle tree with a height of 32 and all elements of 0, using sha2-256, the hash value of each layer is:

[ '0x0000000000000000000000000000000000000000000000000000000000000000',
  '0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b',
  '0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71',
  '0xc78009fdf07fc56a11f122370658a353aaa542ed63e44c4bc15ff4cd105ab33c',
  '0x536d98837f2dd165a55d5eeae91485954472d56f246df256bf3cae19352a123c',
  '0x9efde052aa15429fae05bad4d0b1d7c64da64d03d7a1854a588c2cb8430c0d30',
  '0xd88ddfeed400a8755596b21942c1497e114c302e6118290f91e6772976041fa1',
  '0x87eb0ddba57e35f6d286673802a4af5975e22506c7cf4c64bb6be5ee11527f2c',
  '0x26846476fd5fc54a5d43385167c95144f2643f533cc85bb9d16b782f8d7db193',
  '0x506d86582d252405b840018792cad2bf1259f1ef5aa5f887e13cb2f0094f51e1',
  '0xffff0ad7e659772f9534c195c815efc4014ef1e1daed4404c06385d11192e92b',
  '0x6cf04127db05441cd833107a52be852868890e4317e6a02ab47683aa75964220',
  '0xb7d05f875f140027ef5118a2247bbb84ce8f2f0f1123623085daf7960c329f5f',
  '0xdf6af5f5bbdb6be9ef8aa618e4bf8073960867171e29676f8b284dea6a08a85e',
  '0xb58d900f5e182e3c50ef74969ea16c7726c549757cc23523c369587da7293784',
  '0xd49a7502ffcfb0340b1d7885688500ca308161a7f96b62df9d083b71fcc8f2bb',
  '0x8fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb',
  '0x8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab',
  '0x95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4',
  '0xf893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17f',
  '0xcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa',
  '0x8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9c',
  '0xfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167',
  '0xe71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d7',
  '0x31206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc0',
  '0x21352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544',
  '0x619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a46765',
  '0x7cdd2986268250628d0c10e385c58c6191e6fbe05191bcc04f133f2cea72c1c4',
  '0x848930bd7ba8cac54661072113fb278869e07bb8587f91392933374d017bcbe1',
  '0x8869ff2c22b28cc10510d9853292803328be4fb0e80495e8bb8d271f5b889636',
  '0xb5fe28e79f1b850f8658246ce9b6a1e7b49fc06db7143e8fe0b4f2b0c5523a5c',
  '0x985e929f70af28d0bdd1a90a808f977f597c7c778c489e98d3bd8910d31ac0f7' ]

For a merkle tree with a height of 32 and all elements of 0, using keccak256 (sha3), the hash value of each layer is:

// keccak256 zero hashes
    bytes32 internal constant Z_0 =
        hex"0000000000000000000000000000000000000000000000000000000000000000";
    bytes32 internal constant Z_1 =
        hex"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5";
    bytes32 internal constant Z_2 =
        hex"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30";
    bytes32 internal constant Z_3 =
        hex"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85";
    bytes32 internal constant Z_4 =
        hex"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344";
    bytes32 internal constant Z_5 =
        hex"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d";
    bytes32 internal constant Z_6 =
        hex"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968";
    bytes32 internal constant Z_7 =
        hex"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83";
    bytes32 internal constant Z_8 =
        hex"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af";
    bytes32 internal constant Z_9 =
        hex"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0";
    bytes32 internal constant Z_10 =
        hex"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5";
    bytes32 internal constant Z_11 =
        hex"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892";
    bytes32 internal constant Z_12 =
        hex"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c";
    bytes32 internal constant Z_13 =
        hex"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb";
    bytes32 internal constant Z_14 =
        hex"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc";
    bytes32 internal constant Z_15 =
        hex"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2";
    bytes32 internal constant Z_16 =
        hex"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f";
    bytes32 internal constant Z_17 =
        hex"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a";
    bytes32 internal constant Z_18 =
        hex"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0";
    bytes32 internal constant Z_19 =
        hex"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0";
    bytes32 internal constant Z_20 =
        hex"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2";
    bytes32 internal constant Z_21 =
        hex"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9";
    bytes32 internal constant Z_22 =
        hex"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377";
    bytes32 internal constant Z_23 =
        hex"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652";
    bytes32 internal constant Z_24 =
        hex"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef";
    bytes32 internal constant Z_25 =
        hex"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d";
    bytes32 internal constant Z_26 =
        hex"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0";
    bytes32 internal constant Z_27 =
        hex"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e";
    bytes32 internal constant Z_28 =
        hex"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e";
    bytes32 internal constant Z_29 =
        hex"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322";
    bytes32 internal constant Z_30 =
        hex"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735";
    bytes32 internal constant Z_31 =
        hex"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9";

References

[1] Ethereum 2.0 Deposit Merkle Tree
[2] Formal Verification of Ethereum 2.0 Deposit Contract (Part I)
[3] 2020年论文 End-to-End Formal Verification of Ethereum 2.0 Deposit Smart Contract
[4] 2021年论文 Verification of the Incremental Merkle Tree Algorithm with Dafny

Guess you like

Origin blog.csdn.net/mutourend/article/details/123283054