比特币网络

作者: 云天明ytm_ltd | 来源:发表于2017-07-10 16:19 被阅读314次

    P2P网络

    无中心化的身份对等网络是比特币网络的基础。具有如下特点:
    1、网络拓扑结构:没有中心节点,节点之间全互联。
    2、节点身份:所有节点身份地位同等。既是服务提供者,又是服务消费者。
    3、扩展比特币网络(extended bitcoin network):指代所有包含比特币P2P协议、矿池挖矿协议、Stratum协议以及其他连接比特币系统组件相关协议的整体网络结构。

    扩展比特币网络拓扑

    节点类型分工

    节点之间还是有分工的。每个比特币节点都是路由、区块链数据库、挖矿、钱包服务的功能集合。
    1、比特币网络核心客户端(Bitcoin Core)包括这4个功能:钱包、矿工、完整区块链、网络路由节点。
    2、全节点这个全指的是拥有完整的区块链副本。全节点可以不借助其他节点就可以完成校验交易。
    3、轻量级节点:只保留一部分区块链交易(与自己相关的区块链),采用“简易支付验证(SPV)”的方式来完成交易验证。
    挖矿节点可以是全节点,也可以是SPV节点。


    节点类型分工

    网络发现

    1、新节点
    新加入的节点,需要与已经存在的节点通信,就需要遵循基本的规则:这是TCP/IP网络,端口号8333与已知的对等节点建立连接。
    接下来就要开始握手。
    2、握手消息
    这里约定握手使用的语言和沟通内容。
    ▷ PROTOCOL_VERSION
    常量,定义了客户端所“说出”的比特币P2P协议所采用的版本(例如:70002)。
    ▷ nLocalServices
    一组该节点支持的本地服务列表,当前仅支持NODE_NETWORK
    ▷ nTime
    当前时间
    ▷ addrYou
    当前节点可见的远程节点的IP地址
    ▷ addrMe
    本地节点所发现的本机IP地址
    ▷ subver
    指示当前节点运行的软件类型的子版本号(例如:”/Satoshi:0.9.2.1/”)
    ▷ BaseHeight
    当前节点区块链的区块高度
    3、第一次握手
    新节点当中会有一个长期稳定运行的节点名单(这些叫seed node)。或者也可以启动时指定一个dns种子节点。
    新节点启动,向已经存在的节点发送version握手消息。对方反馈verack,有其他特别需求时也会返回verision。

    第一次握手

    4、第二次握手
    第一次握手后,新节点把自己的IP地址给对方(addr),对方得到后发送到整个网络。新节点继续发出想要得到对方所知道的所有IP地址的要求(getaddr),对方节点返回消息后,新节点从中寻找距离自己最近的对方节点。这样将新节点就加入网络。
    这个节点还有其他工作,当自己断网重连后寻找新节点,其他节点断网重连后提供帮助。


    第二次握手

    如果新节点是全节点

    新节点准备成为全节点,那么需要一系列的步骤完成同步过程。
    新节点一般只有创世区块(0号区块),它发送version消息(BaseHeight字段标示了一个节点当前的区块链高度(区块数量)),双方握手后会交换一个getblocks消息,就知道各有多少个区块。老节点发送inv消息说你还差多少个(哈希一下)。新节点说getdata,你给我吧。老节点给新节点,新节点验证哈希,说:对,这就是我缺少的。
    需要说明的是,为减轻网络负担,inv消息一般一次只包括500个区块。也就说上述消息发送,区块同步是在新节点与多个老节点之间逐一依次进行的。这个过程一直重复,直到同步完成。


    区块同步过程

    轻量型节点SPV节点

    SPV节点只需下载区块头,而不用下载包含在每个区块中的交易信息。由此产生的不含交易信息的区块链,大小只有完整区块链的1/1000。SPV节点不能构建所有可用于消费的UTXO的全貌,这是由于它们并不知道网络上所有交易的完整信息。
    举例,全节点就像拥有这个世界完整地图的游客,虽然携带不方便,但是查起来容易,SPV节点就像一个游客只有一张简易地图,只有 城市名称,你去往哪个城市,得从出发地开始一路走着问着才行。


    SPV节点同步区块头

    也就是,全节点验证交易的方式是沿着区块链按时间倒序一直追溯到创世区块的数千区块及交易,SPV节点是先验证区块形成的链,通过检查在其上面的区块将它压在下面的深度,再把区块链和交易关联起来来验证交易。再具体一点,SPV节点会通过请求merkle路径证明以及验证区块链中的工作量证明,来证实交易的存在性。但是它的最大问题是可以验证交易的存在,但是对于不存在的交易却无能为力,因为它不像全节点维护这完整的区块链。对此,就有可能发生漏洞攻击。
    由于SPV节点需要读取特定交易从而选择性地验证交易,这样就又产生了隐私风险。与全区块链节点收集每一个区块内的全部交易所不同的是,SPV节点对特定数据的请求可能无意中透露了钱包里的地址信息。解决的方法是过滤器。

    Bloom过滤器

    Bloom过滤器是一个允许用户描述特定的关键词组合而不必精确表述的基于概率的过滤方法。它能让用户在有效搜索关键词的同时保护他们的隐私。在SPV节点里,这一方法被用来向对等节点发送交易信息查询请求,同时交易地址不会被暴露。

    就像之前的游客,当他到处询问“教堂街32号”的时候也就泄露了自己的目的地。他可以说:我要去带有“堂”字的街道,或者“教”字开头的街道。
    具体步骤:
    1、SPV节点会初始化一个不会匹配任何关键词的“空白”Bloom过滤器。
    2、SPV节点会创建一个包含钱包中所有地址信息的列表,并创建一个与每个地址相对应的交易输出相匹配的搜索模式。
    3、SPV节点会把每一个搜索模式添加至Bloom过滤器里,这样只要关键词出现在交易中就能够被过滤器识别出来。
    4、对等节点会用收到的Bloom过滤器来匹配传送至SPV节点的交易。
    具体过程:

    Bloom过滤器数组里的每一个数的初始值为零。关键词被加到Bloom过滤器中之前,会依次通过每一个哈希函数运算一次。该输入经第一个哈希函数运算后得到了一个在1和N之间的数,它在该数组(编号依次为1至N)中所对应的位被置为1,从而把哈希函数的输出记录下来。接着再进行下一个哈希函数的运算,把另外一位置为1;以此类推。当全部M个哈希函数都运算过之后,一共有M个位的值从0变成了1,这个关键词也被“记录”在了Bloom过滤器里。

    向简易Bloom过滤器中增加关键词“A”

    再向简易Bloom过滤器中增加关键词“B”,就是重复上述过程。不同的是如果该位的0在增加A时已经变成1,那么再次遇到该位就保留1。这样增加越多,准确度将降低了。

    当过滤器建好之后,对等节点将每个交易的输出值代入过滤器中验证。那些匹配的交易会被传送回SPV节点。为回应来自SPV节点的getdata信息,对等节点会发出一条只含有和过滤器匹配的区块的区块头信息,以及与之相匹配的交易的merkle树。这一对等节点还会发出一条相匹配的交易的tx消息。

    交易池和UTXO池

    每个节点还维护着一个未被确认的交易列表,叫交易池。细分为两种:
    1、刚刚加入的交易,还未被确认(交易池)
    2、由于网络延迟等原因,找不到父交易的子交易(孤立交易池)
    新加入交易池的交易,会先在孤立池中寻找父交易,找到之后,就会退出孤立池,进入交易池,等待确认。

    交易池和孤立交易池(如有实施)都是存储在本地内存中,并不是存储在永久性存储设备(如硬盘)里。更准确的说,它们是随网络传入的消息动态填充的。节点启动时,两个池都是空闲的;随着网络中新交易不断被接收,两个池逐渐被填充。

    UTXO数据库,也称UTXO池,保存的是UTXO数据,这个池不像交易池那样变化那么大,交易池每个节点都不一样,而UTXO池基本相同。UTXO池可以在内存,也可以在硬盘。还需要说明的是,UTXO池只包含确认过的交易。

    警告消息

    警告消息并不经常使用,但在大多数节点上都有此功能。警告消息是比特币的“紧急广播系统”,比特币核心开发人员可以借此功能给所有比特币节点发送紧急文本消息。
    警告通过公钥进行加密签名。对应的私钥是由核心开发团队的一些特定成员所持有。这样的数字签名可以确保虚假警告不会在网络中传播。
    收到警告消息的节点会验证该消息,检查是否过期,并传播给其所有对等节点,从而保证了整个网络中的快速传播。

    参考内容:
    《精通比特币》

    相关文章

      网友评论

        本文标题:比特币网络

        本文链接:https://www.haomeiwen.com/subject/dwzshxtx.html