微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何将 JSON 树结构转换/转换为默克尔树

如何解决如何将 JSON 树结构转换/转换为默克尔树

我正在运行一个网络服务器,我在其中接收 JSON 格式的数据并计划将其存储在 Nosql 数据库中。下面是一个例子:

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

我曾考虑过使用 Merkle 树来表示我的数据,因为 JSON 也是一种树状结构。

本质上,我想做的是将我的数据存储在(或作为)更安全的分散式树状结构中。许多实体将有权从中创建、读取、更新或删除 (CRUD) 记录。理想情况下,这些 CRUD 操作需要从网络中的其他实体进行验证,这些实体也将保存数据库的副本。就像在区块链中一样。

我遇到了设计/概念问题,我正在尝试了解如何将我的 JSON 转换为 Merkle 树结构。这是我的 Node 类:

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

我对它的概念/设计很感兴趣,因为我不知道它是如何工作的。知道如何在 Merkle 树中保存/存储我的 data_example 对象吗? (有可能吗?)

解决方法

您可以通过首先将您的字典转换为类对象形式,然后递归遍历树,对子节点散列的总和进行散列来创建默克尔树。由于默克尔树需要单个根节点,因此任何在最顶层具有多个键的输入字典都应该成为空根节点的子字典(默认键为 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)

输出:

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')])]) 

使用有效负载中的内容更新树:

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

输出:

MTree(1039734050960246293,[MTree(5730292134016089818,'newVal1'),'subval3')])])

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。