有向无环图(DAG)技术白话解读

区块链技术非常热门,但随着越来越多人使用比特币、以太坊等区块链,使得效率低下的问题越来越突出。尤其是2017年6月以来,ICO市场爆炸式增长,人们疯狂的购买以太坊用于投资ICO,导致以太坊网络经常严重延迟。有些人为了能加快以太坊上的转账,甚至将手续费(Gas费用)调高到几百美金。这已经严重违背了区块链作为去中心化支付手段的初衷。

为此,扩容已经成了当前区块链技术发展的重要议题。并出现了分片、侧链、DPoS等扩容解决方案。

除了这些对现有区块链改进的方案之外,还出现了一项受到广泛关注的技术:有向无环图,即Directed Acyclic Graph(DAG)

网上关于DAG的资料并不很多,仅有的一些资料也非常学术性,较难理解。本文尝试用较易理解的方式来解释下什么是DAG技术。

我们知道,区块链技术是一种链式数据库结构,每个区块就像铁链一样,环环相扣。

DAG其实与数组、排列、区块链一样,也是一种数据结构。

但与区块链不同,DAG将最长链共识改成最重链共识。传统区块链上,新发布的区块会加入到原先的最长链之上,并且以所有节点都认为最长的链为准,依次无限蔓延。而DAG中,每个新加入的单元,不仅仅只加入到长链里的一个区块,而是加入到之前的所有区块。假设当你发布新交易时,前面有两个有效区块,那么你的区块会主动同时链接到前面两个之中,DAG 中的每个新单元,验证并确认其父单元,以及父单元的父单元,慢慢可达创世单元,并将其父单元的哈希包含到自己的单元里面。随着时间递增,所有交易的区块链相互连接,形成图状结构,如若要更改数据,那就不仅仅是几个区块的问题了,而是整个区块图的数据更改。DAG这个模式相比来说,要进行的复杂度更高,更难以被更改。下图是一个网状的DAG结构:

最著名的应用DAG技术的项目是IOTA,IOTA改进了DAG,并提出了Tangle(缠绕)方案。即要验证新的交易前,只要直接验证之前的两个交易,这也使得在这两个交易之前所有被验证过的交易得到间接验证。在IOTA的Tangle中,有一个权重积分的概念,所谓权重积分是指它自身的权重与它验证过的所有交易的自身权重之和。在DAG 结构中,交易总是自己创建并发布。从理论上看,攻击者总是可以建构比它要推翻掉的那个交易权重更高的交易用以双花。

看了以上文字后,是否有点晕了,没关系,下面,我通过图形来形象的解释一下:

首先来看区块链,区块链是一种链式数据结构,如下图:

而DAG的数据结构则可以用下图来表示:

在上图中,1和2号是创世节点;第3个节点产生时,只需要确认1号和2号的交易;第4个节点产生时,只需要确认2号和3号,以此类推。

上图是已经经过拓扑排序后的图,比较好理解。它也可以表示成网络图结构,如下图:

如果还没搞懂,那我们再用服装缝制工艺来表示区块链和DAG数据结构(虽然比方不是很合适,但便于普通人理解):

下图是平针针法,就好像区块链,是一个单链的结构。

下图是回针针法,每次产生新的节点(针眼)后,需要往回走一针,就好比DAG,需要有之前的两个节点同时进行确认。


DAG不是区块链技术,但是现在通过DAG技术实现的去中心化网络仍旧被归在区块链板块中。目前比较流行的除了上文提到的IOTA外,还有ByteBall(字节球),xDAG,以及SPECTRE。这些项目都在基础的DAG结构上做了优化处理。

DAG技术才刚刚起步,有很多不完善的地方,但我相信该技术的发展前景会非常良好。目前IOTA的TPS(每秒交易次数)可以达到600-900笔,已经超过paypal的交易能力。随着应用的人更多,执行效率会更高。这是DAG技术与区块链技术最大的不同:区块链技术的效率会随着应用的增加而降低,而DAG却恰恰相反。

(本文尽量用浅显的比方解释DAG,不当之处望谅解,我们正在做相关产品开发,有兴趣可关注)


http://www.bcfans.com/zhuanlan/kuankecaijing/23777.html

  • 10
    点赞
  • 55
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
以下是一个简单的C++ DAG类的构建: ```c++ #include <iostream> #include <vector> using namespace std; class DAG { private: vector<vector<int>> adjList; // 存储图的邻接表 vector<int> inDegree; // 存储每个节点的入度 public: // 构造函数 DAG(int numNodes) { adjList.resize(numNodes); inDegree.resize(numNodes, 0); } // 添加一条有向边 void addEdge(int u, int v) { adjList[u].push_back(v); inDegree[v]++; } // 拓扑排序 vector<int> topologicalSort() { vector<int> result; vector<bool> visited(adjList.size(), false); // 找到所有入度为0的节点 for (int i = 0; i < adjList.size(); i++) { if (inDegree[i] == 0 && !visited[i]) { visited[i] = true; result.push_back(i); // 更新相邻节点的入度 for (int j = 0; j < adjList[i].size(); j++) { int neighbor = adjList[i][j]; inDegree[neighbor]--; } // 重置i,从头开始找入度为0的节点 i = -1; } } return result; } }; int main() { DAG dag(6); dag.addEdge(0, 1); dag.addEdge(1, 2); dag.addEdge(1, 3); dag.addEdge(2, 4); dag.addEdge(3, 4); dag.addEdge(4, 5); vector<int> result = dag.topologicalSort(); for (int i = 0; i < result.size(); i++) { cout << result[i] << " "; } return 0; } ``` 在上面的代码中,我们定义了一个DAG类来表示有向无环图,它包含两个成员变量:邻接表 `adjList` 和每个节点的入度 `inDegree`。我们可以使用 `addEdge` 方法向图中添加一条有向边,并使用 `topologicalSort` 方法执行拓扑排序来得到一个可行的执行顺序。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值