如何将 JSON 树结构转换/转换为 merkle 树
Posted
技术标签:
【中文标题】如何将 JSON 树结构转换/转换为 merkle 树【英文标题】:How can I convert/transform a JSON tree structure to a merkle tree 【发布时间】:2021-08-07 12:30:01 【问题描述】:我正在运行一个 Web 服务器,我在其中接收 JSON 格式的数据并计划将其存储在 NoSQL 数据库中。这是一个例子:
data_example =
"key1": "val1",
"key2": [1, 2, 3],
"key3":
"subkey1": "subval1",
.
.
我曾想过使用 Merkle 树来表示我的数据,因为 JSON 也是一种树状结构。
本质上,我想做的是将我的数据存储在(或作为)更安全的去中心化树状结构中。许多实体将有权从中创建、读取、更新或删除 (CRUD) 记录。理想情况下,这些 CRUD 操作需要从网络中的其他实体进行验证,这些实体也将持有数据库的副本。就像在区块链中一样。
我遇到了设计/概念问题,我正在尝试了解如何将我的 JSON 转换为 Merkle 树结构。这是我的节点类:
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 对象吗? (有可能吗?)
【问题讨论】:
【参考方案1】:您可以通过首先将字典转换为类对象形式来创建 Merkle 树,然后递归遍历树,对子节点哈希的总和进行哈希处理。由于 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)
输出:
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'), MTree(6, [MTree(1, 1), MTree(2, 2), MTree(3, 3)]), MTree(-78872064628455629, [MTree(-8491910191379857244, 'subval1'), MTree(1818926376495655970, 'subval2'), MTree(1982425731828357743, 'subval3')])])
【讨论】:
构建树的聪明方法,谢谢!但是,在这种情况下如何使用 CRUD 操作来修改我的结构?假设我会收到一个带有有效负载的更新请求:“key1”:“newVal1” 如何更新树中节点的值? 建议的解决方案也不考虑嵌套对象或嵌套对象列表,因为列表将使用 str() 直接转换为字符串以上是关于如何将 JSON 树结构转换/转换为 merkle 树的主要内容,如果未能解决你的问题,请参考以下文章