首页 > 解决方案 > 如何同步区块链中的所有节点

问题描述

我在这里尝试做的有两个部分 - 1. 创建区块链结构和 2. 启用 3 个节点之间的 P2P 通信。第 1 部分可以很容易地完成,因为网上有多个关于如何编写区块链结构的资源。这是我为第 1 部分所做的:

# Creating "getdata" request payload
def create_payload_getdata(tx_id):
    count = 1
    type = 1
    hash = bytearray.fromhex(tx_id)
    payload = struct.pack("<bb32s", count, type, hash)
    return payload

# Print req/res data
def print_response(command, req_data, res_data):
    print("")
    print("Command: "+command)
    print("Request:")
    print(binascii.hexlify(req_data))
    print("Response")
    print(binascii.hexlify(res_data))

if __name__ == '__main__':
    # magic value for the main network
    magic_value = 0xd9b4bef9
    tx_id = "fc57704eff327aecfadb2cf3774edc919ba69aba624b836461ce2be9c00a0c20"
    peer_ip_address = '104.199.184.15'
    peer_tcp_port = 8333
    buffer_size = 1024

    # Create Request Objects
    ver_payload = create_payload_ver(peer_ip_address)
    ver_msg = create_message(magic_value, 'version', ver_payload)
    ver_ack_msg = create_message_verack()
    get_data_payload = create_payload_getdata(tx_id)
    get_data_msg = create_message(magic_value, "getdata", get_data_payload)

    # Establish TCP connection
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((peer_ip_address, peer_tcp_port))

    # Send message "version"
    s.send(ver_msg)
    res_data = s.recv(buffer_size)
    print_response("version", ver_msg, res_data);

    # Send msg "verack"
    s.send(ver_ack_msg)
    res_data = s.recv(buffer_size)
    print_response("verack", ver_ack_msg, res_data)

    # Send msg "getdata"
    s.send(get_data_msg)
    res_data = s.recv(buffer_size)
    print_response("getdata", get_data_msg, res_data)

    s.close()

但是,对于第 2 部分,我不确定如何在区块链发生变化时让所有 3 个节点同步它们自己的区块链(即向区块链添加一个区块)。所有 3 个节点都可以充当客户端和服务器,但不能同时充当两者。例如,在下图中,节点 1 是客户端,节点 2 是服务器。节点 3 不会参与交易,但一旦节点 1 和节点 2 之间的交易完成,它将更新自己的区块链。

在此处输入图像描述

关于如何在 3 个节点之间同步区块链的简单代码片段,甚至是指向在 Python 中实现套接字的区块链同步的链接都会有所帮助。

标签: pythonsocketsnetworkingblockchainp2p

解决方案


好吧,比特币从向同行询问库存开始。这是一个哈希值和一个块的高度。对等点检查他们是否已经拥有此块并检查它是否与他们正在使用的检查点相同,如果他们还没有与此库存对应的块并且哈希与其检查点相同,则他们保存库存。他们一直在询问库存,直到他们的库存一直到链尖为止。此时,他们递归地请求与他们保存的库存相对应的每个块。一旦他们获得了区块,他们就会对其进行验证并保存——随时更新 UTXO 集和 txindex(如果启用)。这称为 IBD,在节点离线时完成。当一个节点在线并找到一个块时,找到该块的对等点将与它拥有的所有对等点一起“传闻”该块。基本上,它将哈希和高度(是块的库存)发送给所有连接的对等点,如果对等点还没有该块,那么它会询问块数据并获取块。然后所有对等点都这样做,他们将新块的清单发送给所有连接的对等点(除了他们从中接收块的对等点)。

我不知道在 python 中遵循同步代码的任何简单方法(尽管谷歌搜索应该使用结果(搜索玩具加密货币 python),但它不在 python 中,而是适用于基于 DAG 的区块链,但我正在编写过程中以下同步代码(它还没有完成并且非常混乱)。它是用 rust 编写的,并使用我在 tcpstreams/sockets 之上构建的自制 rust p2p 库

TLDR;新节点询问自他们拥有的最后一个区块以来区块的哈希列表,然后他们保存此列表并向对等方请求相应的区块。现有节点在听到新块时向连接的节点发送哈希和高度对,当节点收到此消息时,他们检查是否有该块 - 如果没有,则他们要求块数据,验证块,保存它并制定它。然后他们将相同的哈希和高度对发送到所有连接的节点。

我希望这有助于回答你的问题!


推荐阅读