第七章 区块链验证过程

1、概述

为了保证交易的合法以及整个系统的安全,区块链在运行过程中会进行各种各样的校验,比如支付验证、交易验证等,本章将对这些验证的目的及原理进行介绍。

支付验证、交易验证是两个不同阶段的验证。

  • 支付验证是轻客户端验证自己的UTXO是否存在的过程。

  • 交易验证是验证节点验证交易是否合法的过程,只有合法的交易才会添加到候选区块中。

2、SPV简单支付验证

在分布式账本中,只是记录了一笔笔的交易明细,并没有记录每个人的余额。当一个用户想知道自己的余额是多少的时候,其实就是把隶属于本人的所有UTXO累加起来即可。

如何验证自己有多少个UTXO呢?当然可以遍历整个分布式账本,但是这种方式不但会占用大量的空间,效率也极其低下。所以中本聪提出了SPV来解决这个问题。

2.1 SPV验证过程

SPV的基本原理是找到当前用户所有的UTXO并证明这些交易存在在主链上。所以需要解决两个问题:找到用户所有的UTXO,证明这些交易在主链上。

问题1:找到用户所有的UTXO
作为普通用户,不可能保存完整的分布式账本(目前已经超过80G了),只有验证节点才会存储(目前有1W多个)。所以想找到一个用户的所有UTXO及区块信息,普通用户是无法办到的。

目前的解决方法是:当用户A想要查询自己的UTXO时,会向所有节点发送查询请求,验证节点通过布隆过滤验证所有交易,找到满足条件的UTXO,组装成查询结果返回给用户A。

布隆过滤器是一种便于插入、查询的数据结构,具体原理可以自己查查。在此处,其实是把用户A的地址作为过滤条件。这样既能达到查询A持有的UTXO的目的,又能保护A的地址。

为了减少空间占用,返回结果并不需要包含所有的交易数据,主要内容如下:

  1. 区块头。
  2. 交易的hash认证路径。认证路径指的是默克尔树中与该UTXO相关的所有节点。如下图所示,假设需要确定23节点是否存在,只需要知道24、12、6、1节点,既能计算出树根0的hash值。
    在这里插入图片描述

问题2:证明交易在主链上
用户A已经拿到了所有隶属于自己的UTXO,下面去验证这些UTXO的有效性。

  1. 下载主链的区块头信息(大概几百兆)。
  2. 根据获取UTXO查询结果,由下而上计算默克尔树根的hash值。
  3. 把第二步的结果与比本地存储的区块中的默克尔树根进行对比,如果不匹配,则直接放弃。
  4. 查看所在区块的确认次数,如果超过6次,则认为该UTXO已经生效。

2.2 SPV的缺点

SPV在提升了查询效率的同时,也有一些问题:

  1. 误差率越来越高:由于布隆过滤器并不是精确查询,随着区块不断增多,其误差率会越来越高。
  2. 可能受到“可锻性攻击”。这个场景主要发生在侧链,侧链上的交易信息会经过加密、签名之后,然后做hash,生成一个唯一的交易号给区块链。问题在于签名结果的某个字节改动,并不会影响验签。这样,攻击者就可以改变签名结果,hash后生成的交易号就完全不同了。这样会造成第二个交易号成功了,但是第一个失败了,付款方就需要重新支付一笔。

对于如何攻击我是外行,我想按照上面的逻辑,是不是把支付方的请求截获了就可以了。

3、交易验证

交易验证是验证节点验证每一笔交易是否合法的过程,这个过程只有验证节点可以做,轻节点由于没有完整的区块链数据,不能执行验证过程。验证通过的交易才会添加到候选区块中进行挖矿。主要验证以下几个方面:

  1. 余额是否充足?
    在本地的UTXO集合中查找到该笔交易的所有输入所在的区块,判断支付金额是否充足。
  2. 是否存在双花问题?
    在上一步查找的区块高度之后,是否存在对这些UTXO的支付行为,从而保证这些UTXO没有被双花。
  3. 是否是自己的钱?
    验证解锁脚本,包括验签、持有者地址比较等。
  4. 收款方是否合法?
    验证加锁脚本,判断收款方是否是合法地址。

这个过程的描述比较简单,以后有机会研究源码的话,可以补充一下。

参考资料

布隆过滤器(BLOOM FILTER)、SPV和比特币
验证双花的两种机制——比特币交易验证和支付验证

发布了48 篇原创文章 · 获赞 34 · 访问量 19万+

猜你喜欢

转载自blog.csdn.net/u013252773/article/details/103957223
今日推荐