原创: 闪电 黄世亮 通往百万TPS之路——BCH的UTXO证明和分片技术(一)
第0章 引言
今天我们来探讨一个非常前沿的技术,BCH的UTXO证明。接下来要在UTXO证明的基础上讨论真正的革命性技术——UTXO分片。
第1章 UTXO的“物理实体”
UTXO叫非花费输出,我们所有的比特币本质上就是一堆UTXO。我们今天是技术讨论会,我们假定在坐的各位都知道什么是UTXO,我就直接跳过这一个环节。
UTXO的“物理实体”是什么?
UTXO都是存储在节点上的,UTXO集的物理实体是一个数据库文件,现在使用的数据库技术叫levedb,这个数据库保存了BCH所有的UTXO,它是随区块高度进行更新的。也就是平均10分钟更新一次,删除掉已经花费的UTXO,更新新构造出来的UTXO。
一笔具体的UTXO主要包含四个字段
1生成这笔UTXO的交易的txid; 2生成这笔UTXO的交易的输出序列号index。因为大部分交易是一个或多个输入,多个输出,第一个输入序列号是0,第二个是1。 3锁定脚本lockscript。 4是金额value
全网所有的UTXO存储在levedb上,目前的组织结构是这样的
txid index => amount lockscript height coinbase
我们可以形象地认为现在的UTXO是一个excel表存储,第一列是txid,第二列是序列号,第三列是金额;第四列是锁定脚本,第五列是区块高度,第五列代表这笔UTXO是否是coinbase交易输出,如果是则是1,如果不是则是0。因为coinbase交易输出需要100个确认才能花费,这是挖矿的成熟区的概念,所以会有这么一个字段来区别非coinbase交易。
第2章 现在的UTXO是怎么生成的?
如果你运行一个完整节点,肯定是要下载区块的,但从来没有听说过要下载UTXO对吧。
其实现在的UTXO是从区块文件中回溯出来的。一个节点下载区块的同时,节点会历遍区块文件找出所有未花费输出,并在本地构造出一个UTXO数据库,每下载一个新区块,UTXO数据库也要更新一次。 一个完整节点存储的主要数据就分成两部分,所有的交易数据全部存在区块链中,而UTXO集被提炼出来存在在UTXO集数据库中。
现在的比特币网络,是一个P2P网络,但网络中传输的数据全是区块文件和交易本身,并不会传输UTXO数据库。
因为UTXO集是比特币最重要的数据之一了,有人就在想,我能不能让比特币的网络也能传输UTXO集。
这就是设计UTXO证明的出发点。
第3章 我们来重新构造一个UTXO数据库
现在的UTXO数据使用的是Levedb,这是一个非常简单的数据库,但不包含区块链思维,我们来设计一个包含区块链思维的UTXO数据库。
我们使用一个二叉树来存储所有的UTXO,二叉树的叶子就是一笔UTXO,包含了txid、序列号、锁定脚本、金额和coinbase识别号,然后哈希一次,构成叶子节点。两两叶子再哈希一次,构成第二层节点,然后一直下去,构成根节点。
通往百万TPS之路——BCH的UTXO证明和分片技术(一)
我们把这个根节点的哈希值称为UTXO证明。
根节点的哈希值会由挖矿节点存进coinbase交易里的一个输出里的OP_Return里。但这样不是一个简洁的设计,一个好的设计是通过一次硬分叉,在区块头文件里增加一个字段,用来存储UTXO证明。
比如现在是50万高度,完整节点会依据现有所有的区块文件,回溯出一个UTXO集,再使用二叉树的形式保存起来,以一个数据库的方式存放。全网将会有唯一的UTXO集数据存在。
当有节点加入网络时,就可以向全网别的节点真正下载UTXO集,并且通过UTXO证明来证明下载到的UTXO集不是伪造的。
这里描述的是静态的UTXO集生成和下载,但区块链是动态的,平均10分钟会更新一个区块,UTXO集也就更新了。
第4章 实现UTXO动态更新
因为挖矿节点,平均每十分钟挖出一个块,并且会依据新的区块对上一个UTXO集进行删除已经花费掉的UTXO和增加新的未花费的UTXO。使用这种二叉树的算法,是很方便删除和增加UTXO集的。
更新过后,新生成一个UTXO集数据库,和一个UTXO证明。
但问题来了,一个UTXO集数据库现在已经是2G大小,平均10分钟要更新一个UTXO集,新加入的节点平均10分钟根本还来不及下载完,10分钟下载2G的数据实在是要求太高了。
同时让一个节点向全网广播2G的UTXO数据,所有需要下载UTXO集的节点都向这样的节点索要数据,那这样的节点也是会崩溃的。
那该怎么设计?答案是使用区块链模型,将UTXO这个数据库也使用区块链来构造和更新。但这个区块链始终是0到100个块之间循环。即平均100个区块更新一个UTXO集数据,而中间使用一个小区块来补充UTXO集。
比如50万高度挖矿节点生成一个UTXO集,并且在区块头里纳入一个UTXO证明,我们记这一个UTXO区块为0高度UTXO区块。
然后在50万零1高度出了一个新块,这时矿工节点会对50万零1高度的区块进行回溯,回溯出一个UTXO区块,记为1高度UTXO区块。并且将这两个UTXO高度的哈希值再哈希存入区块头,以当成UTXO证明。
0高度UTXO区块和1高度UTXO区块,加起来就可以回溯出最新的全网UTXO集。
……
一直到第50万零99高度,这样UTXO区块链就形成了从0到99个区块这样一条短链。
所有其他完整节点,就可以在这0到99高度的时间内下载完所有的UTXO区块,然后在本地构造出一个完整的UTXO集。
当新的矿池节点挖出了第50万零100个区块时,它就会重新生成一个0高度的UTXO区块和一个第100高度的UTXO小区块,并将上一个0高度的UTXO区块在本地删除掉。
在接下来,每当全网生成一个新的比特币区块,那UTXO区块就会删掉最旧的一个UTXO区块,并且增加一个新的UTXO区块。
就这样一直循环。
这样其他需要下载UTXO集的节点就有足够多的时间下载完所有的UTXO区块,并在本地重构出UTXO集,并且也不会对单个提供UTXO区块下载服务的节点太大的压力,因为是可以构成一个P2P网络来传输UTXO区块。
第5章 结束语
UTXO证明整个原理大致就是这样。这样就可以实现全网共同维护一个统一的UTXO集数据库,并且可以实现P2P网络传播UTXO数据,也可以更新UTXO。