当前位置:   article > 正文

以太坊EIP-1186:RPC-Method to get Merkle Proofs - eth_getProof_0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b

0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470

1. 引言

以太坊的区块头中包含了3个Merkle Patricia Tree的根:

  • 1)stateRoot:State树是一棵全局的树,它的key是sha3(ethereumAddress),即账户地址的hash值。其存储的值value为rlp(ethereumAccount),即账户信息的rlp编码。其中账户信息是一个[nonce,balance,storageRoot,codeHash]的四元组,其中storageRoot指向账户的Storage树。

    • Storage树:一般的外部账户Storage为空,而合约账户通常会储存一定的数据,这些数据就是存储在合约账户的Storage树中,storage树中的key与账户地址和其中实际存储的key有关,其value值为合约定义的value值。
  • 2)transcationsRoot:每一个区块都会有一棵Transactions树,其key为rlp(transactionIndex)(交易在区块中的编号,0,1…),其value值为经过rlp编码的交易。在实际情况中该树并不会真的存储到数据库中,只是在生成block以及校验block的时候用于得到当前区块的TransactionsRoot。实际中一条交易连同同一区块的其他交易以及区块的uncles是被存储在一个条目中的。

  • 3)receiptsRoot:每一个区块都会有一棵Receipts树树,其key为rlp(transactionIndex)(交易在区块中的编号,0,1…),其value值为经过rlp编码的交易收据。在实际情况中该树并不会真的存储到数据库中,只是在生成block以及校验block的时候用于得到当前区块的ReceiptsRoot。实际中同一个区块的交易收据会一起编码然后存储在一个条目中的。【Receipts 本质上为 pieces of data showing the effect of each transaction。】

在这里插入图片描述

在这里插入图片描述
基于以上设计,light client可查询验证以下信息:

  • 1)某交易是否包含在某特定区块中?【transaction树】
  • 2)告知过去30天,由某地址释放的所有类型为X的事件(如某众筹合约达成目标)。【receipt树】
  • 3)某账号当前的balance。【state树】
  • 4)某账号是否存在?【state树】
  • 5)假装在某合约上运行某交易,输出为?【state树】

其中1)和4)可很直观计算:server仅需找到该object,然后 fetches the Merkle branch (the list of hashes going up from the object to the tree root) and replies back to the light client with the branch。
5)计算起来会更复杂:需构建a Merkle state transition proof——为a proof which make the claim “if you run transaction T on the state with root S, the result will be a state with root S', with log L and output O” (“output” exists as a concept in Ethereum because every transaction is a function call; it is not theoretically necessary)。【To compute the proof, the server locally creates a fake block, sets the state to S, and pretends to be a light client while applying the transaction. That is, if the process of applying the transaction requires the client to determine the balance of an account, the light client makes a balance query. If the light client needs to check a particular item in the storage of a particular contract, the light client makes a query for that, and so on. The server “responds” to all of its own queries correctly, but keeps track of all the data that it sends back. The server then sends the client the combined data from all of these requests as a proof. The client then undertakes the exact same procedure, but using the provided proof as its database; if its result is the same as what the server claims, then the client accepts the proof.】

2. EIP-1186:eth_getProof

以太坊EIP-1186的eth_getProof RPC接口提供的proofs,对于secure Layer2技术很重要。这些proofs可验证accounts outside the client。

以太坊的state树存储了the state of accounts and their storage,可简单通过创建Merkle Proof来验证每个值。以太坊的eth_getProof RPC接口会创建Merkle Proofs for accounts and Storage values。结合区块头中的stateRoot,可offline验证任何account或storage value。从而使得无法运行light client 的IOT设备或移动APP也可在仅知a trusted blockhash的情况下,验证responses from an untrusted source。

eth_getProof
返回the account- and storage-values of the specified account including the Merkle-proof。

变量类型有:

  • 1)DATA:20字节,为账号地址。
  • 2)ARRAY:32字节。为array of storage-keys which should be proofed and included。具体见eth_getStorageAt
  • 3)QUANTITY|TAG:为区块号,或字符串“latest”/“earliest”。

返回值为:
Object:为account object,包含了:

  • 1)balance: QUANTITY:为the balance of the account。具体见eth_getBalance
  • 2)codeHash: DATA:32字节,为hash of the code of the account。对于没有code的account,返回值为"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"。
  • 3)nonce: QUANTITY:nonce of the account。具体见eth_getTransactionCount
  • storageHash: DATA:32字节,为SHA3 of the StorageRoot。All storage will deliver a MerkleProof starting with this rootHash。
  • 4)accountProof: ARRAY:为Array of rlp-serialized MerkleTree-Nodes, starting with the stateRoot-Node, following the path of the SHA3 (address) as key。
  • 5)storageProof: ARRAY:为Array of storage-entries as requested. Each entry is a object with these properties:
    • key: QUANTITY:请求的storage key
    • value: QUANTITY:为storage value
    • proof: ARRAY:为Array of rlp-serialized MerkleTree-Nodes, starting with the storageHash-Node, following the path of the SHA3 (key) as path。

其中:

  • [nonce, balance, storageHash, codeHash ]在黄皮书中定义为了an account-object的4 fields,用于存储a hash of the account-object in order to keep track of changes。
  • accountProof:为 MerkleProof for the account starting with a stateRoot from the specified block。
  • storageProof:为MerkleProof for each requested storage entry starting with a storageHash from the account。

如请求:

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "eth_getProof",
  "params": [
    "0x7F0d15C7FAae65896648C8273B6d7E43f58Fa842",
    [  "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" ],
    "latest"
  ]
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

返回的结果类似为:

{
  "id": 1,
  "jsonrpc": "2.0",
  "result": {
    "accountProof": [
      "0xf90211a...0701bc80",
      "0xf90211a...0d832380",
      "0xf90211a...5fb20c80",
      "0xf90211a...0675b80",
      "0xf90151a0...ca08080"
    ],
    "balance": "0x0",
    "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470",
    "nonce": "0x0",
    "storageHash": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
    "storageProof": [
      {
        "key": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
        "proof": [
          "0xf90211a...0701bc80",
          "0xf90211a...0d832380"
        ],
        "value": "0x1"
      }
    ]
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

3. proof for non existent value

若某address或storage value不存在,则proof中需要提供足够的data来验证。即意味着client需要follow the from the root node and deliver until the last matching node。若the last matching node is a branch, the proof value in the node must be an empty one。对于leaf-type,it must be pointing to a different relative-path in order to proof that the requested path does not exist。

4. possible Changes to be discussed

  • instead of providing the blocknumber maybe the blockhash would be better since it would allow proofs of uncles-states.
  • in order to reduce data, the account-object may only provide the accountProof and storageProof. The Fields balance, nonce, storageHash and codeHash could be taken from the last Node in the proof by deserializing it.

参考资料

[1] EIP-1186: RPC-Method to get Merkle Proofs - eth_getProof
[2] 以太坊详解 之 Merkle Patricia Tree
[3] Merkling in Ethereum

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/369243
推荐阅读
相关标签
  

闽ICP备14008679号