DHT
DHT代表分布式哈希表,本质上是一个分布式的键值数据库,其中网络的每个成员都可以存储某些内容,例如,关于自己的信息。
TON中的DHT实现与IPFS中使用的Kademlia的实现本质上类似。任何网络成员都可以运行一个DHT节点,生成密钥并存储数据。为此,他需要生成一个随机ID并通知其他节点自己的存在。
为了确定在哪个节点上存储数据,使用了一种确定节点与密钥之间“距离”的算法。算法很简单:我们取节点的ID和密钥的ID,执行XOR操作。值越小,节点越近。任务是尽可能接近密钥的节点上存储密钥,以便其他网络参与者可以使用同样的算法,找到可以给出此密钥数据的节点。
通过密钥查找值
让我们看一个查找密钥的示例,连接到任何DHT节点并通过ADNL UDP建立连接。
例如,我们想找到托管foundation.ton站点的节点的地址和公钥。假设我们已经通过执行DNS合约的Get方法获得了该站点的ADNL地址。ADNL地址的十六进制表示为516618cf6cbe9004f6883e742c9a2e3ca53ed02e3e36f4cef62a98ee1e449174
。现在我们的目标是找到拥有此地址的节点的ip、端口和公钥。
为此,我们需要获取DHT密钥的ID,首先我们将填充DHT密钥模式:
dht.key id:int256 name:bytes idx:int = dht.Key
name
是密钥类型,对于ADNL地址使用“address”,例如,要搜索分片链节点 - 使用“nodes”。但密钥类型可以是任何字节数组,取决于您正在查找的值。
填写此模式,我们得到:
8fde67f6 -- TL ID dht.key
516618cf6cbe9004f6883e742c9a2e3ca53ed02e3e36f4cef62a98ee1e449174 -- our searched ADNL address
07 61646472657373 -- key type, the word "address" as an TL array of bytes
00000000 -- index 0 because there is only 1 key
接下来 - 从上面序列化的字节获取DHT密钥ID的sha256哈希。它将是b30af0538916421b46df4ce580bf3a29316831e0c3323a7f156df0236c5b2f75
现在我们可以开始搜索。为此,我们需要执行一个具有模式的查询:
dht.findValue key:int256 k:int = dht.ValueResult
key
是我们DHT密钥的id,k
是搜索的“宽度”,它越小,搜索越精确,但可查询的潜在节点越少。TON节点的最大k为10,通常使用6。
我们填充这个结构,序列化并发送请求,使用adnl.message.query
模式。您可以在另一篇文章中阅读更多关于此的内容。
作为回应,我们可以得到:
dht.valueNotFound
- 如果未找到值。dht.valueFound
- 如果此节点上找到了值。