简体   繁体   English

如何将 JSON 树结构转换/转换为 merkle 树

[英]How can I convert/transform a JSON tree structure to a merkle tree

I'm running a web server, where I receive data in JSON format and planning to store it in a NoSQL database.我正在运行 web 服务器,我在其中接收 JSON 格式的数据,并计划将其存储在 NoSQL 数据库中。 Here is an example:这是一个例子:

data_example = {
    "key1": "val1",
    "key2": [1, 2, 3],
    "key3": {
        "subkey1": "subval1",
        .
        .
        }
      }

I had thoughts about using a Merkle tree to represent my data since JSON is also a tree-like structure.由于 JSON 也是树状结构,因此我曾考虑使用 Merkle 树来表示我的数据。

Essentially, what I want to do is to store my data in (or as) a more secure decentralized tree-like structure.本质上,我想做的是将我的数据存储在(或作为)更安全的去中心化树状结构中。 Many entities will have access to create, read, update or delete (CRUD) a record from it.许多实体将有权从中创建、读取、更新或删除 (CRUD) 记录。 These CRUD operations will ideally need to be verified from other entities in the network, which will also hold a copy of the database.理想情况下,这些 CRUD 操作需要从网络中的其他实体进行验证,这些实体也将持有数据库的副本。 Just like in blockchain.就像在区块链中一样。

I'm having a design/concept problem and I'm trying to understand how can I turn my JSON into a Merkle tree structure.我遇到了设计/概念问题,我试图了解如何将我的 JSON 变成 Merkle 树结构。 This is my Node class:这是我的节点 class:

class Node:
    """ class that represents a node in a merkle tree"""
    def __init__(data):
          self.data = data
          self.hash = self.calculate_some_hash()  # based on the data or based on its child nodes

I'm interested in the conception/design of this as I couldn't figure out how this can work.我对此的概念/设计感兴趣,因为我无法弄清楚它是如何工作的。 Any idea how to save/store my data_example object in a Merkle tree?知道如何在 Merkle 树中保存/存储我的 data_example object 吗? (is it possible?) (可能吗?)

You can create a Merkle Tree by first converting your dictionary to a class object form, and then recursively traverse the tree, hashing the sum of the child node hashes.您可以通过首先将字典转换为 class object 形式来创建 Merkle 树,然后递归遍历树,对子节点哈希的总和进行哈希处理。 Since a Merkle Tree requires a single root node, any input dictionaries that have more than one key at the topmost level should become the child dictionary of an empty root node (with a default key of None ):由于 Merkle 树需要单个根节点,因此在最顶层具有多个键的任何输入字典都应成为空根节点的子字典(默认键为None ):

data_example = {
  "key1": "val1",
  "key2": [1, 2, 3],
  "key3": {
     "subkey1": "subval1",
     "subkey2": "subval2",
     "subkey3": "subval3",
    }
}
class MTree:
   def __init__(self, key, value):
      self.key, self.hash = key, None
      self.children = value if not isinstance(value, (dict, list)) else self.__class__.build(value, False) 
   def compute_hashes(self):
       #build hashes up from the bottom
       if not isinstance(self.children, list):
          self.hash = hash(self.children)
       else:
          self.hash = hash(sum([i.compute_hashes() for i in self.children]))
       return self.hash
   def update_kv(self, k, v):
      #recursively update a value in the tree with an associated key
      if self.key == k:
         self.children = v
      elif isinstance(self.children, list):
         _ = [i.update_kv(k, v) for i in self.children]
   def update_tree(self, payload):
      #update key-value pairs in the tree from payload
      for a, b in payload.items():
         self.update_kv(a, b)
      self.compute_hashes() #after update is complete, recompute the hashes
   @classmethod
   def build(cls, dval, root=True):
       #convert non-hashible values to strings
       vals = [i if isinstance(i, (list, tuple)) else (None, i) for i in getattr(dval, 'items', lambda :dval)()]
       if root:
          if len(vals) > 1:
             return cls(None, dval)
          return cls(vals[0][0], vals[0][-1])
       return [cls(a, b) for a, b in vals]  
   def __repr__(self):
      return f'{self.__class__.__name__}({self.hash}, {repr(self.children)})'        

tree = MTree.build(data_example) #create the basic tree with the input dictionary
_ = tree.compute_hashes() #get the hashes for each node (predicated on its children)
print(tree)

Output: Output:

MTree(-1231139208667999673, [MTree(-8069796171680625903, 'val1'), MTree(6, [MTree(1, 1), MTree(2, 2), MTree(3, 3)]), MTree(-78872064628455629, [MTree(-8491910191379857244, 'subval1'), MTree(1818926376495655970, 'subval2'), MTree(1982425731828357743, 'subval3')])]) 

Updating the tree with the contents from a payload:使用有效负载中的内容更新树:

tree.update_tree({"key1": "newVal1"})

Output: Output:

MTree(1039734050960246293, [MTree(5730292134016089818, 'newVal1'), MTree(6, [MTree(1, 1), MTree(2, 2), MTree(3, 3)]), MTree(-78872064628455629, [MTree(-8491910191379857244, 'subval1'), MTree(1818926376495655970, 'subval2'), MTree(1982425731828357743, 'subval3')])])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM