设为首页 | 收藏本站 | 关于我们 | 广告服务
 
 
当前位置:首页 > 科技资讯 > 技术前沿
技术前沿
银行科技人员告诉你,什么是区块链——细说区块链
来源:中国金融电脑  作者:漆英  日期:2017/6/5

(中国工商银行软件开发中心 漆英)

 

  引言

 

  目前,区块链已成热点话题,区块链应用的研究大潮正在金融科技领域涌动,因此,作为金融科技人员,了解区块链的技术原理很有必要,而且与区块链相关的技术(算法或思想)也是值得我们学习借鉴的。但关于区块链知识的干货”(中本聪的论文)是基于前人若干研究论文基础上的,太,难以消化;关于区块链知识的水货”(市面上的书籍),长篇累牍地贩卖XX和展望应用,而对技术讲得不清不楚,太,技术营养为足。面对这种情况,我利用业余时间来,从程序员及架构师的视角编写了系列科普博客--《戏说区块链》,并在软件开发中心的技术BBS上发表,获得了好评。本文由此系列博客整理而成。

 

  §1 区块链的基本结构

 

  区块链可以看做一类新型的数据结构,我们分几个方面进行讨论。

 

  1.1 链,非链

 

  我们先看看一类重要的数据结构:链。许多语言实现了该结构,例如,C语言。链形式如下:

 

 

  

 

 

  链上很容易进行两类操作:

 

  1、对节点操作:查询(定位)节点、增加节点、删除和插入节点、调整节点的位置;

 

  2、对节点中的数据进行操作,如,修改Date(先定位到该节点)

 

  例如,将节点N插入到N2N3之间

 

  

 

 

  可以看出上述链是一个松耦合的数据结构,它是为方便各类操作而设计的。

 

  下面我们看看相反的场景:我们探寻一种数据结构,要求它方便各类操作(防篡改)

 

  构造这样的粘合体:将数据块的指纹嵌入到下一个数据块中,作为下一个数据块的数据部分,参与下一个数据块的指纹计算。如图所示。这就是所谓的区块链,它不是我们通常意义下说的链。

 

  

 

  上述两类结构非常不同:

 

  首先,前者是松耦合的,后者是紧耦合的。区块链的这种紧耦合结构,使得对数据的修改很困难——任何链节点的变动,将会导致其指纹的变动,从而对其右侧的相邻节点产生了变动,如此下去,就产生了连锁反应,即任何链节点的变动将引起其右侧的所有节点逐次变动。

 

  其二,前者是空间中的,后者是时间轴上的。C中的链本身就是定义为一种内存中的数据结构,其链上的节点()可以在链上移动,如,用链进行冒泡排序。考察区块链的任何两相邻节点,右侧节点不能产生于左侧节点之前,因为右侧节点必须包含左侧节点的指纹。由此可见,区块链是按时间先后关系进行链接的,实际上它是一个历史链”(呵呵,强烈建议将其换成这个名字),该历史的起点就是上述标号为0的那个区块,称为创世纪历史只能沿时间轴前进(即可以在链的最右侧添加新的区块),而不能对历史修改。

 

  上述设计在分布式网络中有一个缺陷:网络的相关节点都要存整个区块链,随着链越来越长,数据量将越来越大。能否在保持前述历史特性的前提下,网络节点只存放与自己相关的数据呢?

 

  仍利用数据块的指纹特点,这时,我们将指纹视为存根,即由存根”(key)可以在网络上找到原始数据”(value),它们的关系是(keyvalue),且由存根不变来保证原始数据不变。在此条件下,网络节点可以只存放链和与自己相关的数据,对不存放的数据,可以仅存放存根。区块分为两部分:区块头(很少字节)和数据集装箱,仅区块头做上述链,而数据集装箱由其存根代表。如图,某网络节点存放的区块链及数据(整个链和相关的数据块)

 

  

 

  1.2 指针,非指针

 

  C中的链是通过指针连接的,其指针就是地址(指针指向一个数据块在内存中存储的地址)。通过寻址,就可以找到指针指向的数据块在内存中的位置,实现定位功能。

 

  我们再看看区块链中的指针是怎么回事。我们在区块链中取一个数据及其指纹,并将指纹画成就像你按的椭圆形指纹(对应于上节的M)

 

  

 

  如图,数据A(数据块)通过哈希算法H,产生其指纹a,反过来,指纹a代表着数据A。就像犯罪嫌疑人在现象留下的指纹代表着犯罪嫌疑人一样。这就是区块链中的指针的意义,它是线索索引(指纹),而不是空间定位索引(住址)

 

  A对应的a就有双重意义,一是作为指纹,二是作为指针。由于是用哈希值 ,因此这类指针称为哈希指针。引入记号:

 

  

 

  显然,哈希指针并不能直接实现前述的定位功能,就像犯罪嫌疑人的指纹并不能直接得到犯罪嫌疑人的门牌号码。关于这一点,有的书作者没有仔细想,就说哈希指针指向数据的存储位置。这个错误会导大家。我们还可以从另一个侧面来说明其不正确:其一,是先有数据A(它已存储在内存中),再有哈希指针(指纹),没有必要在算出哈希指针值后,将数据移到指针指出的位置;其二,哈希指针值是很大的(256),远大于目前的64位寻址空间;其三,即使有足够大的空间,那么移动数据到哈希指针所指示的位置,会不会与附近的数据块部分重叠?C中,先是向系统申请分配内存(用于存放数据),再将该内存的地址赋给指针。

 

  虽然哈希指针不能实现上述内存中的定位,但借助某种辅助手段还是可以实现某种定位。例如,将(aA)视为(keyvalue),以数据库的方式即可实现快速定位。

 

  利用a借助辅助手段,能找到”A,说明a确实可以看成是指针,只不过它不是通常意义下的地址指针。

 

  1.3 块,非块

 

  第一节最后的图示可以看出,区块链是这样一列奇怪的列车:由一排车头链接着,每个车头外挂着一个数据集装箱,集装箱里装着数据。这节我们看看如何组织集装箱里的数据。

 

  前面我们讲到任何一个数据块可利用Hash函数产生指纹,这个指纹反过来作为指针(Hash指针)指向该数据块。若将Hash指针应用于树结构,就是梅克尔树(以发明者命名:Merkle tree),这就是我们需要的组织数据集装箱中数据的特殊材料。

 

  我们看看梅克尔二叉树。

 

  

  叶子节点为数据D,由于是二叉树,故其余节点含两个Hash指针,二叉树的第一层1个节点、第二层2个节点、第三层4个节点、设二叉树为k+1(即叶子节点在k+1),则叶子(数据)个数为 , 从根到叶子需经过k个指针。反过来,若已知叶子(数据)个数为n,则从根到叶子需经过  (底为2)个指针。

 

  根据Hash指针的指纹性质知,叶子节点(数据)的变化都会上向传递到根节点,即任何一个叶子的变化都会引起根节点的变化,反之,只要根节点未变化,就可以认为所有叶子(一组数据)未改变。

 

  回到上节的最后一个图,将根的Hash(浅橙色的)嵌入到区块头中,充当存根”(MerkleRoot),而数据集装箱是一颗梅克尔树,即区块不是而是一颗Merkle “。当然,对Merkle树进行数据打包(即序列化)还是可以变成的。

 

  

 

  1、如何以最小代价验证节点D是树的叶子

  如何验证颗梅克尔树的一个叶子。显然,你不必要提供整颗树,你只需提供叶子和从根到该叶子的路径即可,即 个指针节点,即计算的时间复杂度为 。如图,褐色的路径: ,即提供3个指针节点。

 

  验证过程(从底往上验证):褐色数据DHash值一定是上一层节点数据的左边或右边,该节点Hash值一定是更上一层节点数据的左边或右边,直到根,再到存根。

  这一特性表明,你可以根据需要存一颗残缺的树,例如,你只关心上图中褐色数据,那只中需存放该数据及路径。当然,必要时,你也可以利用残缺的树(事实上只需要存根即可),把整颗树找回来,即从顶(存根)往下,利用哈希指针找。

 

  2、如何判断节点D不是树的叶子

 

  要证明一个数据D不属于某颗梅克尔树的叶子,则没有这么幸运,需要同该梅克尔树的叶子逐一对比(或对比其指纹),当梅克尔树的叶子是按某种规则已排序时,则优化成:只需对比到数据D在排序中应处的位置。

 

  3、在梅克尔树上修改数据也不易

 

  若要修改褐色数据D,则需要沿着上述路径,修改到,从修改数据D开始到修改结束,是一个复杂的事务。因为,所有的叶子数据的修改都涉及到,故几乎不支持对叶子的并行修改(至少在树根处需要等待)。当然,如果这颗梅克尔树作为区块链到了区块链中,那更是修改不了,因为,树根的变化将引起存根的变化,进一步地,在区块链上向右侧引起连锁反应。

 

  4、修改一颗树上的一个叶子之后,如何以最小代价重构这颗树?

 

  重构实际上是自底向上重算图中红线上的红框,当然就是D123。当然,这只是得到一颗树,实际上,你可以得到多颗树,因为这里对兄弟关系不care,所以,调换某红框中两H()的左右再向上计算,你会得到另一颗树,这些树都是符合要求的。

 

  前面论述了二叉梅克尔树,仿此可推广到多叉梅克尔树,要点:

 

  1、各层级数相同,这样,树就很规整,便于处理;

 

  2、所有数据包(如,交易数据)都是放在叶子节点,非叶子节点是下层节点的Hash指针();

 

  3、一个叶子节点可以放多个数据包,即将叶子定义为数据包数组()

 

  综上,区块中的主体是一颗梅克尔树,当然,对其序列化后可以变为数据块

 

  1.4 历史,不能成为历史

 

  利用哈希指针,结合前述内容,我们重新画一下区块链。注:箭头为指针方向,若按数据生成方向则箭头相反,另外,既然是历史链,那时间戳(time stamp)必不可少。至此,确定区块头中的三个最基本的元素:时间戳(Timestam)、指向前一区块(, )的指针(Pre-Hash)、指向数据块(梅克尔树树根)的指针(MerkleRoot)

 

   

 

 

  平时,我们说让历史成为历史吧,意思是说,把历史放一边吧,但这句话在区块链中行不通,因为,区块链是用完整的历史原始数据来检验双重支付(后续专门话题中涉及),即它不能斩断区块链,因此,历史数据清理等动作在这里行不通,由此带来的问题是:随着时间的推移,数据越来越庞大(需要大容量的存储设备,只有加法),检验的范围也就越来越大(导致交易的效率逐步下降,只有减法),在这法的双重作用下,这条区块链最终会走向死亡。当然,会有新的区块链诞生。因此,在区块链的生存期间,不会进行历史数据清理。故,区块链不支持需要做历史数据清理的大数据量应用(第一个缺)

 

  区块链是历史链,入了链的数据是不能被篡改的,即使数据错了也不能修改,从交易层面讲,就是交易不可撤销(没有反交易和冲正);从码农角度讲,程序BUG若影响到数据,那麻烦就大了,数据不能被维护既是优点(不需要这方面的维护人员)也是缺点(不能改错)区块链对业务和程序的质量都要求很严(第二个缺点)

 

  前面,我们知道哈希指针有一个特点:先有数据A再有指针a,即生成方向与指向方向相反。由此Merkle tree的生成过程是自底向上,数据在叶子上,每片叶子的变化都会逐层向上直到影响树根,即树根是热点,这一特性决定了Merkle tree本身不支持大并发量交易(第三个缺点)。但比特币没有用梅克尔树的叶子存账户的可变信息(如余额),从而避开了这一缺点,它是将交易体”(不变)作为梅克尔树的叶子。机制为:网络上并发交易,进入交易池”(缓冲),然后从池子中取出一定数量的交易,一次性生成梅克尔树,打包交易放入区块中,故它是支持大量并发的。但它不支持连续性交易(A转账给BB立即转给C),原因见下述第四个缺点。

 

  如果将区块链作为公有链,那么交易等待需要全网达成共识,比特币设定的等待时间是一个小时,这个漫长的等待时间使得许多商业应用不得不放弃公有链,而选用同盟链。公有链需要等待共识,即不支持强实时性应用(第四个缺点)

 

  §2 关联的密码学知识点

 

  区块链技术是根植于密码学的,本章我们对涉及到的密码学知识给予普及性讲解。

 

  2.1 此哈希亦非彼哈希

 

  前面,我们将a(A的哈希值)视为A的指纹,即a“唯一地确定了A,就像指纹证据能唯一确定罪犯一样。

 

  但哈希我们不陌生,如,有5台服务器,我们希望交易在这5台上较均匀地分布(负载均衡)。解决方案:规定交易的某种属性x(如,交易的序号、交易的账号、交易到达的时间等等)和服务器的某种属性y(如,服务器编号01234),构造一个哈希函数 y = x (mod5),定义分配策略:将交易x分配到服务器y上。

 

  哈希函数 y = x (mod5),在方案中起了映射作用:如图,将7号交易和12号交易都分配到2号服务器上处理。

 

  显然,该哈希函数具有如下特性:

 

  1、单向:即由7能得到2,而从2不能断定是7

 

  2、压缩:将交易域(成千上万的交易)分配到服务器域(5)中,且均匀分布。

 

 

 

  712都对应于2,我们说712产生了碰撞,负载均衡正是利用这种碰撞特性。只要有压缩就会产生碰撞,即使一丁点压缩。鸽笼原理是这样说的:n+1只鸽子飞向n只笼子,一定有一个笼子中有两只(或以上)鸽子(碰撞)。这里说一定,当鸽子数小于笼子数时,就不一定,但还是以某种概率发生碰撞,如,40只鸽子飞向365只笼子的情况。

 

  你可做个测试:假定你小组有40(以上),赌你小组有生日碰撞”(同一天过生日)(什么?小组不足40?——把他女朋友算上)(什么?不想暴露生日?——那你不妨在纸上写上假生日)

 

  利用碰撞进行负载均衡,但碰撞是指纹的死敌,试想若指纹有碰撞,那还能用它来作为证罪的证据么?哈希函数的压缩特性说明哈希函数不具备防碰撞特性,但可以退一步,在一定的应用范围内,找具有碰撞阻力的哈希函数。这类哈希函数很神奇,虽然该哈希函数H存在的碰撞,但:1、在使用它的应用场景中碰不到它;2、故意找它难度大(计算上不可行)

 

  这样,在应用时,就可认为该类具有碰撞阻力哈希函数是无碰撞,其哈希值就可以作为数字指纹。大家熟知的MD5就是这样一个哈希函数,例如,常用MD5做版本或文件的数字指纹,用于验证版本/文件是否被篡改(对下载的文件验证其数字指纹是否为指定的值)或版本是不是最新的。但不幸的是MD5强度不够(它是128):我国密码学家王小云找到了MD5产生碰撞的方法(即打破了上述故意找它难度大的前提),直接导致了MD5逐渐被淘汰和弃用。以位数更多、强度更高的算法代替。

 

  2.2 碰撞,别发生

 

  上节让大家做生日碰撞测试,不知大家感觉如何?反正我开始时,直觉上感觉40人中撞生日的可能性很小(毕竟有365)。事实上,40人中撞生日的可能性(概率)可达89%,当人数达到100人时,撞生日的可能性几乎是100%(69),只要人数达到23,撞生日的可能性就超过50%

 

  撞生日的反面是不撞生日撞生日的概率等于1不撞生日的概率,而不撞生日的概率易计算,设k个人,则他们不撞生日的概率为

 

   

 

 

  由此,我们可以得出一个结论:1(生日)压缩函数一定会产生碰撞;2、即使减少的数量,发生碰撞的可能性还是很高的。那么怎么样产生碰撞阻力?

 

  我们回到上节的鸽笼例子上来,直观地理解一下产生碰撞阻力的方法。

 

 

 

  首先,我们应扩大右边的集合(目标集),即增加笼子数”;

 

  其次,我们应缩小左边的集合(源集),即根据应用场景,使得我们需要的有用子集”(上图橙色)远小于右边目标集。缩小方式有两个维度,一是空间,如,我们的区块是有一定格式和编码要求的,这就排除了不合格的;二是时间上的,如,一万年后的某交易与你现在的交易一毛钱关系没有,完全不用理会这种隔空发生的碰撞。

 

  例如,一万只鸟儿(蓝色集),其中有100只鸽子(橙色集,即应用的有用子集),鸟儿飞向一千只笼子(右边目标集),则可认为鸽子没有碰撞”(没有两只鸽子在同一只笼子中)。但还是有两只鸽子进了同一只笼子,由于它们俩是夫妻,这就要改善飞的规则。

 

  其三,从算法(行为)上构造办法,让鸟儿的飞行相互独立,如,一只一只地放飞,它不知道笼子中的情况。

 

  有了上述三点,情形变为:

 

  鸟儿数 > > 笼子数 > > 鸽子数;分散的飞行行为(算法)

 

  “ > > ”表示远远大于,第一个“ > > ”会产生经常性的碰撞(见鸽笼原理),第二个“ > > ”会产生偶尔碰撞(见生日碰撞),再加上算法,产生碰撞阻力

 

  这样,鸽子就难以碰撞,我们就说符合抗碰撞性(具有碰撞阻力)。这就是避免碰撞戏说中的简易理解。

 

  更严格地讲,(抄一段密码学中严格的描述)作为指纹的Hash函数应具有的性质:

 

   压缩性:输入可以为任意的长度消息,而输出为固定长度的二进值串(128256比特);

   不可逆性:已知输入x,计算其Hashh(x)容易,但已知Hashh,要找到对应的x在计算上不可行;

   抗弱碰撞性:对任意的输入x,找到满足 ,且h(x)=h(y)y在计算上不可行;

   抗碰撞性:找到任意满足h(x)=h(y)的偶对(x,y)在计算上是不可行的。

 

  回到区块链中的区块指纹,选用的是HASH-256,它是符合上述性质的Hash函数(256)。据说要破解它需要等到量子计算机之类的超强机器出现。

 

  有了上述抗碰撞性,可以认为数据A和它的Hasha是一一对应的,它是区块链的理论基石之一。这样,结合第2节的内容,哈希值在区块链中就有两个作用:

 

  1、作为指纹,用于防篡改;

 

  2、作为指针,用于查询。

 

  注:一些文章画箭头线时,没有注意两者之间的区别,易造成混乱,阅读时请注意这一点。

 

 

  2.3 加密?实际是签名

 

  前面我们说明了在区块链技术中使用密码学的指纹,下面我们再看看在交易中使用密码学的签名。

 

  我们知道,交易必须有防伪造和防抵赖,日常商务中靠签名盖章来保证。无纸化环境中使用密码或数字签名,显然数字签名优于密码,因为数字签名可以实现同交易的绑定,即同一个人,不同的交易产生的数字签名不同。

 

  数字签名可以看作与手写签名的机制与作用类似:

 

  1、我能方便地进行签名——用我的私钥进行数字签名;

 

  2、别人能方便地验证是我的签名——请用我的公钥对我的签名进行验证,能通过即是我的签名,否则为仿冒;

 

  3、签名是与特定的内容绑定(不能篡改内容)——内容参与签名的运算,即签名过程的输入是内容(消息)和私钥;

 

  4、签名要考虑效率,显然,手工对多页合同的每页都签名的效率不如先将内容压缩到一页再签名——我们知道Hash函数有压缩功能,可以对压缩结果进行签名。这虽不是必须的但是重要的,因为,签名算法本身在时间上花费与签名内容长度成正比;

 

  数据(消息)通过Hash压缩后叫消息摘要(上节我们知道Hash值在区块链中有2个作用,这是第3个作用:作为消息摘要,用于数字签名)。后续,我们说到签名,就是指对消息摘要的数字签名。

 

  数字签名(也叫电子签名)我们并不陌生,例如,证书(U盾和数字证书):即公钥证书,它是一种数字签名的申明,将公钥与特定使用者(如个人、设备或服务)绑定,向使用者提供公钥,使其用于进行加密等。重要网站通常会将自身证书颁发给客户端(下载、安装或自动下载),你运行命令行:certmgr.msc,就可以看到你电脑中的证书,点开一个证书,你可以在详细信息中看到:颁发者、有效期、公钥、指纹、各种算法等。

 

  比较一下(非对称)加密和签名很有趣(见表)

 

  1、解密与签名对应,都是用自己的私钥,反过来说,使用(自己的)私钥,要么是解密,要么是签名;

 

  2、加密与验证对应,都是用别人的公钥,反过来说,使用(用别人的)公钥,要么是加密,要么是验证;

 

 

  区块链中的交易是基于数字签名的,比特币之类的电子货币常称为加密货币,实际上是数字签名货币。

 

  §3 交易结构

 

  区块链是用来交易的,那么交易内部的结构如何?相关的交易间是如何关联的?

 

  3.1 地址?实际是账户

 

  我们知道,若A通过交易将资金转给B,则A需要知道B的账户。那么,什么代表B的账户呢?B如何开户?假定交易是在公网上公开进行,那么保护个人隐私的措施就很重要,显然,B应该以某种别名代表自己(“账户”),那么,如何取别名?

 

  密码学告诉我们,B可以向CA申请一对公、私钥,即开户,以公钥作为他的别名,交易时,AB的公钥(“别名”)转入资金,B用私钥签名领取资金。

 

  那么,问题来了,公钥作为别名太长,必须做些易用性方面的优化(这个优化思路值得大家学习)

 

  1、将公钥压缩;

 

  2、增加校验位;

 

  3、可书写化;

 

  公钥压缩显然可以用到Hash指纹(160bit),再将指纹参与某种运算,截取局部(如取头4Byte,32bit),前面再加上0x00(4bit),这时,公钥账户变为196位的01串。这里,我们看到Hash的第4个作用:作为压缩函数,用于产生账户

 

  通过上述头两步,得到一个“01”串,下面重点讲讲第3可书写化的设计。设计从两点入手:

 

l   利用大进制,缩减表达式的长度;

 

l   剔除易混淆的字符。

 

  01串是二进制(最小进制)的数,它可以转换为其它进制,如,大家熟悉的10进制和16进制。如,10进制的179

 

 

  下面我们证明这个等式。

 

  我们知道:

 

 

  实际上其它各进制中的数也都可以表示成十制进中数的多项式(底为进制)。即对于一般的T进制,T进制中的k位数

 

 

  其中, 在一个符号集合中取值,这个符号集合中有T个字符,由小到大分别代表012, ,例如,十进制为0129,十六进制中为0129ABCDEF

 

 

  上面分析,我们可以得到两个结论:

 

  1、一个数可以用上述多项式,并通过多项式在各进制中转换;

 

  2、进制越大,表达越短,当然使用的字符越多,进制T的大小等于所使用的字符的个数。

 

  从易用性考虑,表达得越短越好,这就要求我们尽可能多地选取、世界范围大家熟悉的字符,下面我们构造该符号集合及次序:数字字符(10)+英文字符大写(26)+英文字符小写(26)=62个,但有几个易于混淆,应剔除掉:0oO三者中保留o,而I1l三者中保留1,这样就剔除了四个,62-4=58,字符次序为上述次序剔除四个后的左对齐,即最左端:字符1对应序号为0,最右端:字符z对应的序号为58。这就是Base58编码规则。

 

  利用该编码规则和上述多项式方法,可将前述近20001串账户转化成58进制数,转换后为34位的字符串,大大方便了输入。转换后的结果称为公钥地址,该地址不是普通的地址(内存地址或邮箱地址),而是业务角度的账户

 

  我认为,取名为地址很切合实际,类似于邮件地址是邮件的到达,很久以前,通过邮局汇款,也是使用邮件能邮到的地址。类似,这里公钥地址是指资金到达,凭私钥领用资金,即它与对应的私钥挷定,不管谁拥有该私钥,而传统的账户是与人挷定的。另外,区块链也不仅仅用于账(资金),它还用于管理和转移其它资产,所以,称为地址涵盖范围更大,地址就是你的别名

 

  但在这种体系中,没有建立别名与真实的你的对应关系,即没有用户认证机制,天条是:只有私钥证明你是你,一方面:一旦他获取了你的私钥,那他就是你,他就可以使用你的资金了;另一方面:你把私钥弄丢了(忘了),你就证明不了你是你,你就无法使用那笔资金了。

 

  大家看得太闷了吧,烧烧脑(思考题)

 

  1、我们的账号是19位,如果按上述Base58,可以缩为几位?

 

  2、设上题的答案是N位,嫌34位的公钥地址太长,如何压缩到N?如果这样做了,会是什么情况?

 

  3.2 简单交易

 

  我们先引入一种新的交易观念。

 

  看看一个简单的资金流转过程:某人X指定一笔资金给你(A)你领取这笔资金ƒ你将该笔资金指定给别人B(使用该笔资金)

 

  上述过程中,当然“X的工作;“‚”“ƒƒ是你A的工作,传统思维中,我们是将“‚ƒƒ”视作两个交易,而新的交易观念就是你尽可能地推迟领取,只是在使用该笔资金时才领取该笔资金,将领取使用视为一个交易事务。

 

  简单交易:在上述一领就用的基础上再加一句:一用全用。即假定某人通过交易1使A获得了一笔资金,现在,A通过交易2,完成上述两个动作:领取该笔资金和将这笔资金全部指定给B

 

  作场景假定是:不通过可信任的第三方(银行)A自己做交易并向大众展示。我们考察交易2的要素。

 

 

  来源:这笔资金来源于交易1,由前面章节可知,交易1的指纹就代表交易1,所以,来源是个哈希指针(指纹),指向交易1。由于不是通过可信任的第三方,不能简单地说,来源”=A和金额,否则X可以冒充A,或A修改金额。

 

  去向:去向当然是B,但由于是展示给大家,故B不希望实名制,设计时,可用B的公钥 代表B(实际上是上节的公钥地址)

 

  签名:交易2A做的,为了防伪造和防抵赖,必须由A对交易2的关键要素进行签名,同时,A的签名也表示他对交易1(指纹)也签名了,即表示他对交易1中指定A的资金的领取。

 

  验证脚本:交易是通过可验证性来保证,平台有一部,它根据交易的类型生成验证脚本,而不是交易员写的。这里的就是代码,呵呵,开发人员是不是一下高大上了?代码即

 

 

 

  X通过交易1将资金转给A(设已得到了大家的认可)A通过交易2将资金转给B,大家需要通过验证脚本来验证交易2的合法性。交易2是由A做的,并由A签名的,如果将验证它的验证脚本放在交易2中,则有自证的嫌疑,实践中,将验证交易2验证脚本放在交易1中,相当于X将资金转给A时,加了句:凭A的私钥领取这笔资金(即交易2中要有A对交易1签名)

 

  A通过交易2完成领取这笔资金并用掉这笔资金,其前提是A此时记得私钥,一旦遗忘了私钥,则A将失去他的资金(他做不了交易2),而又无法找回私钥。这也就是我们上节说的区块链中的账户(地址)没有用户认证机制。(区块链中的第五个缺点)

 

  3.3 智能合约

 

  接着上一节,我们将交易分为两部分:将签名放入来源”(IN),将验证脚本放入去向”(OUT),并作相应的变形:

 

  1、资金的流向:交易1中的OUT部分(与交易2相关的)A_idA地址”(A的公钥 变形得到),是交易1指定的资金转给A。交易2OUT部分表明A又将资金转给B(地址为B_id)

 

  2、签名的效果:交易2A签名内容Message为两部分:交易2(去掉(A签名, ))和交易1中的OUT部分(与交易2相关的),即该签名是一石二鸟:对交易1OUT部分签名(解锁:签名领用),对交易2签名,表明交易2A(锁定:资金给谁)

 

  3IN中,数据(公钥 )用于声明我是谁(供大家检验)

 

  所谓验证,别人(不是做交易2A)就是在已承认交易1的前提下,用程序(非人工)对交易2的合法性进行验证,分两部分:

 

  1、身份验证:交易2中的 是交易1指定的公钥地址A_id;

  2、签名验证:交易2中的签名是用A的私钥签名,私钥不告诉你,但你可用公钥来验证签名。

 

 

 

  基于上述,我们可以设计一个简单的脚本(由数据和指令组成),该脚本源于交易1OUT(锁定:资金给谁)和交易2IN(解锁:签名领用),若脚本以堆栈方式工作,则需将上述次序反过来。

 

 

 

  这个脚本就是所谓的智能合约,实际上是交易的数字合约”+“验证脚本,再加上运行的平台环境(如,上述栈运行方式)

 

  3.4 组合交易

 

  前面我们对简单交易进行了分析,所谓简单交易是指A获得一笔资金(交易1)的前提下,他将它全部转给B。本节将交易扩展为:A先前已获得了多笔资金(先前交易中),他将它转给不同的人(包括自己)

 

  有了前述的将交易设计成INOUT两部分的思路,进一步地将INOUT设计成数组就可以解决问题。

 

  设这时A作的交易为交易A”,对比简单交易时的结构,我们看看扩展:

 

 

 

  1、输入IN和输出OUT均为数组,形成多对多关系;

 

  2、数组IN每项都有H*N*,其中,H*(指针)指向其前置交易,N*(标号)指明在前置交易H*中的第N*OUT项。即H*N*联合决定了该IN项对应的前置OUT,如,图中红线将两茶色块联系起来了,每一个联系就构成了类似于前述的简单交易的脚本;

 

  3、上述对应表明,交易AIN中各项对过H*N*对应的前置OUT均为A_id(即都是锁定给A);

 

  4、数组IN每项都有A_sig*,表明,都是用A的私钥签名的且公钥为 ,但各组签名的结果A_sig*不一样,原因是,各项签名时,除了对整个交易A外还要拉上对应的前置OUT(这部分各不相同);

 

  5、数组IN每项都按前述简单交易的验证方式进行验证,就完成了整个交易A的验证;

 

  6、数组OUT每项都有一个V*,它是给B*_id的金额,OUT的所有金额之和为输出总金额。IN中每项中就没有显示列出金额,它的金额是从对应的前置OUT中得到,IN的所有金额之和为输入总金额。

 

  组合交易可以看做是一系列的简单交易组成,因此,对组合交易的验证,包括两个方面:一是金额,显然,输出总金额不能超过输入总金额;二是交易的合理性,就是运行一系列(对应于IN部分)简单交易脚本(如,图示的两茶色块构成第一个简单交易脚本)

 

  3.5 账务体系

 

  至此,我们建立起了区块链(基于比特币)账本的三层体系:

 

  1、区块链:每块包含若干交易;

 

  2、交易:每个交易包含若干输入条目(数组IN)和若干输出条目(数组OUT);

 

  3、输入条目(IN)和输出条目(OUT):它是基本单元,但不能独立存在,即它是交易的组成部分。

 

  从上一节可以知道,金额是放在第三级,即交易的每个输入条目(IN)和输出条目(OUT)都有金额,且输入条目(IN)的金额是隐式给出的(它由前置的输出条目(OUT)给定)。示意图:

 

 

 

l   客户A作的交易A:左边为OUT组、左边为IN

 

  • 输出条目(OUT):有两个数(金额,给谁),如,(U1A)(V1B1)等等。还有一个隐含的数:该条目在数组中的序号。
  • 输入条目(IN)中,H()N表示通过Hash值找到其前置交易 ,再通过N( )找到 中OUT组中第个OUT,这些OUT中均说明资金 给A,即为红线所示。输入条目(IN)中金额不必显示地写出来,因为,通过红线找到对应的OUT,其OUT中的金额即是。
  • 交易可以看作资金的集散地,左边IN收集资金,右边OUT散出资金,假定没有手续费,则左边的资金之和等于右边资金之和(记得我们在前面交易时说全部用完),这是可以做到的,因为,交易A中,A将未用完的资金OUT给自己即可。
  • 资金的流向以蓝线表示,它与红线的方向刚好相反,蓝线表示跟踪资金的流向,但它如果通过多次集散是很难跟踪的。

 

  又一次出现了方向相反的箭头线,其意义不同(不要混淆),红线实现上是指针,假定交易都是简单交易,则从当前交易可回朔出一条交易链”(像区块链),会有许多条交易链。当交易不是简单交易时,则回朔稍微复杂,过程像向左递进的绽放烟花”(如,交易A爆出的红线又引爆交易X1X2,其红线又引爆…)

 

  在图中,我将IN的边框画成虚线,表是它只不过是先前某个OUT影子,显然,在账务系统中不应出现重影

 

  思考题:如何避免重影”(双重支付)?

 

  §4 柜员入账

 

  为了更好地理解区块链的运作机制,我们类比银行的账务处理,看看如何入账的。

 

  4.1 竞争上岗

 

  我们脑洞大开地设想有这样一个民主网点

 

  1、网点有若干柜员,柜员拿绩效工资,但其主管是程序,即一切协调事宜均由程序负责;

 

  2、网点有一个交易池,客户按前几节的方式完成交易(类似于客户填完交易单),并将交易单放到交易池中就走了(但交易未记账,平时说的异步方式),只不过是交易单不是纸质的,而是由程序控制的、各柜员可共享和拷贝的电子交易单。

 

  3、网点是用区块链作账本,由柜员将交易池中的交易记账(写入区块链)

 

  我们看看这个网点如何运作。

 

  首先,我们看交易如何记账,回忆区块链的基本结构,区块链中的数据块是一个梅克尔树,它可以装很多个交易,所以,可以批量记账:将交易池中的交易组装成一颗梅克尔树,再生成一个新的区块头,该新区块头含有前一区块头的指纹,即区块链长了一节,如图黄色节:新的区块头+新梅克尔树,这样就完成了交易的批量记账。

 

 

 

  第二,谁来记账?从上述图中可以看出,新加入链(记账)的区块()中含有前一区块()的指纹,区块链的正常增长是一个顺序动作,应一次加一块,这一块的增加(这批记账)可由一个柜员完成。那么问题来了,由哪个柜员记账?这就相当于在一个民主社会如何产生一个临时负责人的问题。石头、剪刀、布、选举、传令牌以及PK能力等都是民主社会中的选择。在我们所设定的场景下,PK柜员的能力”(程序能鉴别的)是个不错的选择,这就是区块链中可选用的各种证明(“能力证明,如,工作量证明、权益证明、股份授权证明)

 

  以工作量证明为例:为了竞争出哪个柜员承担当前的记账柜员,主管(程序)出一道计算迷题,谁先完成谁胜出。由于柜员拿绩效工资,所以,大家争着去解题,但由于这个迷题需要暴力破解,拼的是计算力工作量,故叫工作量证明。

 

  第三,记账频度控制。区块链是历史链,每增加一区块,就是一批交易记账(梅克尔树的叶子全是交易)。当然不希望历史链增长过快,可以给一个时间窗口来限制速度(如,10分钟),即10分钟产生一个区块,但这样就要协调各柜员的时钟,比较困难。重新审视一下我们的需求,时间窗口就不必严格,可追求平均意义下的时间窗口。在工作量证明(做完交卷)的场景下,计算题的难度就可以代表一个时间窗口,实际时间为算得最快的那个柜员的时间。在计算题中加一个调节难度的参数,就可以协调时间窗口和计算力之间的关系。记账频度也是柜员的竞争频度,即链上一次加一块、柜员一块一竞争

 

  4.2 工作量证明

 

  上节我们说民主网点的柜员通过解计算迷题来竞争上岗,那是一个什么样的迷题?

 

  区块链需要计算区块头的指纹,将迷题与该计算结合起来设计:

 

  1、区块头中加一个变量Nonce,这个变量每取定一个值就能得到区块的一个指纹,对该变量随机取数进行试算(暴力破解),一旦计算的指纹合乎要求,就认为解答了迷题;

 

  2、上述计算指纹是用哈希函数,哈希函数有一个很好的性质,就是具有分散性质(散列),也就是指纹会较均匀地分布在总范围内。将总范围划出一块作为目标范围,上述要求表述为计算值落入目标范围(呵呵,像不像玩飞标?),定义目标范围:多少位的数,我们换一个说法,前面多少个0,即定义一个上界(它为定长,表示为16进制为000…000FFF…FFF),这样,上述要求表述为计算值小于上界,以Bits表示上界中0的个数;

 

  3、显然,Bits越大(上界中前面0的个数越多),解的范围越小,迷题就越难(想想飞标),反之,迷题就越容易。上节我们说需要一个难度参数Bits就是该参数。程序需要定期”(如,两周)地去调节这个参数,定期是个时间概念,不好处理,把它转化成好处理的区块个数,即每2016块后调节一次(10分钟产生一块,两周对应2016),调节公式略。

 

  在区块链的基本结构中,我们描述了区块头的基本结构,若要采取工作量证明(POW: Proof of Work),则区块头中需要增加上述两字段,这时完整的区块头为:

 

 

 

  上面说的暴力破解,是对Nonce进行随机取数试算:取定一个Nonce,该区块头就定了,从而指纹就定了,判断该指纹是否满足要求。但计算机的伪随机数是有问题的,它实际是不能全覆盖的循环数列,我们追求全覆盖,因此,程序中是用for循环,即对Nonce0开始逐一试算,直至指纹落入范围,解迷题即是找符合的Nonce

 

  柜员都是用这个程序,那么,大家的迷题是一样么?如果是一道迷题,大家拼的是for循环计算,那个算力最强的柜员必员获胜,这样的竞争就没有意义(每次都是他)

 

  好在还有一个机关:MerkleRoot依赖于交易在梅克尔树叶上的排序,只要在将交易从交易池移入梅克尔树时,增加随机性,就可以保证MerkleRoot不一样,从而各柜员手头的区块头就不一样,这就有了柜员的运气成份,生成MerkleRoot环节类似于对题目的抽签环节。另外,后面的币基交易中柜员还有很大的自由度区分。

 

  上述暴力破解过程称为挖矿,相应地,柜员称为矿工Hash的第5个作用:作为散列函数,用于挖矿

 

  4.3 在网上建个民主网点

 

  将前述的民主网点搬到网络上来如何?

 

  首先,搬到网上后要保持民主的要求,即柜员没有主管”(程序充当主管,协调相关事宜),也就是要求去管理化

 

  其次,搬到网上后要保持共享的要求,即所有柜员能共享账本”(区块链)和交易池。

 

  上述两点对网络提出了明确的需求,刚好P2P(peer to peer)网络能满足这方面的要求,P2P网络我们并不陌生(你回忆一下那些曾经找过的种子”),它实现网络应用层的组网(子网),如,装了电驴的用户形成一个子网,子网中用P2P进行网络视频传播、共享。因此,我们可以利用电驴相同的策略组成一个这样的子网:交易区块被广播、查询和下载,每网络节点视为一柜员,这样就形成了我们需要的民主网点”(虚拟网点)。中本聪的论文就是《比特币:一种点对点的电子现金系统》。这里的点对点“P2P”

 

  该虚拟网点的柜员分布在全世界(但由P2P组网,故可以理解为在一个虚拟网点中),柜员在这个网络中称为节点,具有不同的算力,按前两节的方式,客户向交易池提交交易,柜员(节点)竞争产生区块、进行批量记账,每个柜员(节点)均有全量数据。

 

  搬到网上后,整个系统在程序的协调下按前述原理工作,显然,它是一个去中心化的系统,也是一个共享的分布式系统,还是一个容错、容灾系统。

 

  总结一下:将区块链放到P2P上,1、区块链本身具有不可篡改性;2P2P又保证了数据不会丢失;3P2P实现了数据的共享。它不需要数据维护(也不可做)、不需要灾备、实现了账本共享等。故区块链与P2P二者的结合,形成了超强的分布式数据库。

 

  对柜员(节点)要求可放松,后续的讨论基于如下假设:

 

  • 柜员随时可加入和退出,但应有足够多柜员,以保证P2P网络有效;
  • 柜员中可能有作恶者或不作为者,但守规矩的柜员的算力应大于50%,即常说的占51%(以整数表述)以上。

 

  挖矿仅是数值计算(Hash),竞争使得柜员:1)投入算力:从CPUGPU(图形处理器适合于计算),再到专门的挖矿机。2)改变策略:算力充足或联合矿工,进行并行挖矿,每个进程承包不同的区域,如,不同的交易排列、不同的for循环段,俗称开矿池

 

  竞争使得算力投入不断升级,但因要保证10分钟左右一块的频度,故,只有不断调节难度系数,使难度不断加大,其结果是:

 

  1、因迷题太难,一般算力的矿工无利可图,导致大量小矿工退出,算力越来越集中到少数的柜员手中,民主走向寡头”;

 

  2、大量的算力投入到毫无经济价值的迷题计算中,对能源产生了极大的浪费,这是大家对POW诟病的地方;

 

  3、难度加强,导致指纹范围压缩,碰撞概率增大。我作个改善,用双指纹:指纹1=Hash(区块头(剔除Nonce))、指纹2=Hash(区块头(包含Nonce)),取指纹=Hash(指纹1 || 指纹2)

 

 §5 最终共识

 

  柜员间的利益冲突必然导致入账的冲突,这就需要一个机制,使得记账结果的逐渐地最终一致性

 

  5.1 奖励机制

 

  在公有链中,需要有一种机制驱动柜员记账,以比特币为例:柜员挖矿”(解迷题),胜出则获得产生一区块(批量记账)的权力,于是他向P2P广播他产生的区块,若他的区块有效,则该批交易被记账,并且他获得奖励。比特币的奖励分为两部分:

 

  1、手续费,回忆交易结构,我们知道每个交易都有一组IN和一组OUT,在每个OUT中定义了付出金额,这组OUT的付出金额之和为总付出金额;在每个IN中定义了收入金额(是隐性定义的,即是其对应的来源的OUT),这组IN的收入金额之和为总收入金额。总付出金额不大出总收入金额,其差值为该交易的手续费。由于是批量记账,故柜员获得各交易的手续费之和。

 

  2、奖金(充当货币发行功能,如,比特币),即每产生一个块,则发行一点货币,为了避免发行过量,比特币采取的控制策略为:每4年奖金减半,一定年限后停止发行。

 

  上述两部分的金额,不能体现在前述交易中,1、手续费:由于柜员是竞争记账的,所以,客户A做交易A时,他不知道被谁记账,故他不可能在交易AOUT中指定给记账柜员;2、奖金:这部分资金并没有对应的IN项。为此,每个区块中定义一个特殊交易(币基交易)

 

  

  •  该交易只有一个IN和一个OUT
  •  OUT描述:将手续费(V1)和奖金(V2)给该记账柜员自己(如,地址为My)
  •  IN的前置交易指针为0(即没有前置交易)IN中的原签名部分此时没必要,故开放给柜员任意使用,形成coinbase

 

  柜员可以有目的地使用coinbase字段,例如,你可放一张有名的报纸照片,表明该块的形成时间不早于该报纸上的时间。

 

  另外,手续费类似于服务的小费,多少由你给,但不同的是它是提前设定(客户提交交易时设定,而柜员服务在后),因此,柜员为多争收益,其策略是:手续费多的交易优先记账(纳入区块),而区块产生的频率固定且区块的最大容量有限,这会使那些手续费少(或无)的交易延期记账,甚至无限延期,就像钞票少的人乘不上车一样。通常会设定一个时间窗口期,未记账的老化交易将被抛弃。

 

  5.2 竞争升级

 

  类似于军备竞赛,竞争会不断升级。挖矿实力体现为硬实力和软实力,硬实力包括投入大量机器和电力,软实力主要是靠软件,包括算力的有效利用(如,利用显卡的算力计算Hash)、研制专用芯片、算法优化等。

 

  我们看看矿池算法优化:

 

  上节说到柜员有特殊交易(币基交易)用于给自己接收报酬,该交易中有一个字段可以由柜员任意使用,形成coinbase,基于此,我们可以用于设计矿池。

 

  在子段coinbase中定义一个子字段coinbase_nonce(整数变量),与区块头中Nonce类似,用于挖矿,即coinbase_nonce变化使得该交易变化,导致梅克尔树的存根发生变化,从而导致区块头变化。前面,我们说可通过改变交易的排序来导致梅克尔树的存根发生变化,但交易的排序会使整个梅克尔树各节点都要计算,而coinbase_nonce变化,仅是梅克尔树中从该币基交易通向树根通的沿途节点需要计算,故可调整方案:挖矿环节以coinbase_nonce变化取代交易重排序,这样,挖矿就成了coinbase_nonce变化和Nonce变化的双重循环。即:相当于待定区块上安装了两个调旋钮,联合调节音量。待定区块一旦调整好了这两项,就成了合格的新区块,就可向P2P网络提交该区块。双重循环示例:

 

  For( 0<coinbase_nonce<M;coinbase_nonce++){  //外循环

 

      For(nonce=0; nonce<N;nonce++){  //内循环

 

          计算迷题function(区块头);//上述变化都反映到区块头中

 

          If(答案在范围内)return true;

 

          } //内循环

 

       } //外循环

  为了合理利用强大的算力,可以以外循环(coinbase_nonce变化)分段拆分,形成并行工作模式(多进程同时挖矿),如,将coinbase_nonce变化范围[0M]分为若干段,第i[]由第i个进程运算,这样第i个进程的上述代码段的第一句变为:

 

 

  这n个进程既可以由一个柜员(网络节点)运行,也可以分配给若干柜员节点分头运行,如果是后者,就需要设计一个利益分配机制,自动产生分配交易(从略)

 

  一旦产生了一个合格的新区块(某个进程产生的或网络中竞争对手产生的),主控进程立刻中止当前正在进行的各挖矿进程,并以这新区块为基础启动下一波挖矿。这就是矿池挖矿场景。

 

  5.3 不服?PK到共识

 

  柜员挖矿竞争中,会不会有人偷跑?回答是不能,因为,一下个块的迷题(区块头)中含有当前块的指纹,即在当前块还没有形成时,没办法开始下一块的迷题计算(挖矿)。虽不能偷跑,但可以提前作好准备(如,提前生成梅克尔树),一旦收到当前块的广播,你需确认是否认可它,认可它是指你将以它为基础(即将它的指纹嵌入待建的区块中)计算下一块的迷题。

 

  由于是在P2P网上进行,你可能在间隔不长的时间内,收到了ABC广播的当前块,你收到的次序为ABC,但实际生成次序或别人收到的次序为BCA,谁也不服谁,出现如下情形(分叉)

 

 

  此时,你是认可”ABC中哪一个?程序就要给出一个认可的规则,当然是在区块正确的前提下(包含不合格交易的区块将被抛弃),规则如下:

 

  • 第一优先权(长度):能使区块链更长的区块具有优先权,显然,上述图中B不满足;
  • 第二优先权(交易数量):包含较多交易的区块优先;
  • 第三优先权(区块的时间):区块中时间戳越早越优先,但时间戳是柜员(节点)填入的(需要存疑),所以,只有时间戳合乎一定的要求才是合格的区块。

 

  一旦你选定了当前块”(如,C),你将以它为基础上进行下一块的构造,此时你心目中当前认可的区块链为:

 

 

 

  每个柜员都有一条心目中当前认可的区块链,之所以说当前是因为由于长度优先原则使得你后续可能作出调整,如,C枝长度没竞争过A(C被剪枝)。由柜员(假定柜员都是守规矩”)各自遵循上述规则形成,从创世纪区块出发,逐步PK成长出一条区块链,相当于柜员对区块进行投票(如,上述你对区块C投了一票),我们以区块的灰度表示投票的多少(达成共识的程度),则该区块链左边色深、右边色浅。(称为共识链)

 

 

 

  上述规则中的长度优先和奖励机制(类似于猜对有奖”),避免了柜员坚持个人己见,这会使柜员及时调整自己的错误选择,因此,共识链上的分叉只发生在柜员还没有发现自己错误时,而发现错误只是个时间问题,故共识链上的分叉只发生在最右边几块,且向左概率逐节减少。一定块数(比特币设为6)后分叉的概率为0,即为全网柜员都认可”(即达成了共识),这就是共识机制:依规竞争,大浪淘沙,达成共识。

 

  §6 隐性信息显性化

 

  前面我们说:区块链是历史链,历史信息自有其讲述的规律。

 

  6.1 有链,何需要表?

 

  前面我们的区块链图示中,链是逻辑的,即许多信息是隐性的,使用很不方便的,例如,长度优先就要找出最长的分支(立起来看,长度就是高度),这就要计算出链(含分支)上每个区块的高度,区块的高度就是不包括在区块中的隐性信息(可从区块链结构中推导出来)。从效率角度来讲,应将这些隐性信息显性化,并存储起来以便重用该信息(避免每次去推导)

 

  本节我们以最简单的信息(如,高度)为例,说明表的必要。

 

  在上节中,假定我们先前已知(需保存起来)区块X的高度为100,则重用这个信息得出后续区块AC的高度为101。但从信任角度讲,网络节点不会接受别的网络节点推导出的信息,即不会接受我已推导出区块X的高度为100,请你使用这句话。

 

  折衷的办法是:网络节点建立自用的本地辅助信息库。即根据需要仅从区块()中将隐性信息显性化并存入本地数据库中。即由区块()导出辅助信息库,反之不许可,这是可信所要求。

 

  如果你是一个新加入的柜员(网络节点),你应该只信任区块,加入的第一件事是下载网上的区块,并据此建立自己的辅助信息库用于求链长。我们可以动手设计一个方案:

 

 

  以区块()的指纹作为Key、区块作为Value,则以(KeyValue)建表(Key作为主键),由于可以由区块直接计算出Key,这就把所有区块装入一个表中,对该表增加一列(前置区块的键(指纹))preKey,它是包含在区块()Value中,从中取出,则区块链转化成区块表blocktab(KeyValuepreKey),再对该表增加一列:区块在链中的高度High,这时blocktab(KeyValuepreKeyHigh),依此表我们可推导出High列的值:

 

  初始:设创世纪块(KeyValueif(preKey==0),则High=1);

 

  for(游标(Select * from blocktab when High=null)){

 

      设当前游标纪录为(Key_XValue_XpreKey_XHigh_X);

 

      Update 游标指定的纪录 set High_X=(Select High from blocktab when Key =preKey_X)+1;//为前置区块的高度加1 }

 

  最长的分支的高度就是链的长度:

 

      Select max(High) from blocktab

 

  根据共识机制,对淘汰分支裁剪,即还有删除(或标记删除)

 

  建立辅助信息库后,该柜员收到新的区块后,就可以很方便地(而不是从头计算)得到它的High,如,设新区块为new,则取上述更新语句即可(“游标指定的纪录为新区块、*_X*_new)

 

  仿此你可以建立双向追溯表:(KeyValuepreKeypostKey)

 

  总之,对于查询(以及检验时的查询)建立辅助信息库是必要的。

 

  联盟链中,各成员盟常常将自己的已经存在的中心数据库作为区块链辅助信息库,这样,不断大大改善了区块链应用的效率(与查询相关),还可以将不愿公开给盟友的信息放到辅助信息库中,而不放到区块链中。

 

  思考题:为何不把区块在链中的高度写到区块头中?

 

  6.2 避免双重支付(1)

 

  双重支付是指A做了两笔交易(同时做或不同时做):一个交易将资金转给B,另一个交易又将同一笔资金转给C

 

  有了前述的辅助信息库,就可以利用它通过查询来判断一个交易是不是双重支付,从而避免双重支付(当然也避免了多重支付)

 

  为方便理解,我们先假定所有交易都是简单交易和币基交易(即交易只有一个IN和一个OUT,币基交易的IN是无前置交易的),在这种假设下,简单交易的IN(指针)指向前置交易(OUT),如此下去直至一个币基交易,这样,你就找到了一条交易链。按此你可将每一个交易归到某条交易链中,呵呵,区块链中的所有交易拿出来,就变成了你的一碗交易面条。类比区块链(区块换成交易”)交易链创世纪交易(币基交易),有指向前置交易的指针(IN中前置交易的H())

 

  交易链区块链很相似,双重支付实际上是交易链的分叉(一个前置交易分出两个后续交易来),回忆区块链如何处理分叉的:柜员的职责是自己保证自己做好,即每个柜员自己的区块链是一条链(不分叉),但多个柜员的放在一起时,起点相同(创世纪块),通过共识算法剪枝,形成长长的树干的区块树(即只是树的顶端存在分叉)

 

  那么如何处理交易链分叉?(1)与区块链相同,柜员的职责是自己做好自己,即保证自己的交易链不分叉。由于已入账的交易一定在一个区块中,一个区块一定是被一个柜员加入到区块链中,因此,柜员的责任保证了在其认可的区块链上(含他新加上的区块)的所有交易链不存在分叉。(2)又与区块链相同,所有的柜员的交易链组合在一起,可能出现分叉。显然,交易链的分叉是由于柜员选择不同的区块链分枝而导致的。而在那颗长长的树干的区块树上,长长的树干部分是所有柜员都认可的,故交易链在树干的部分是不会分叉的,也就是说交易链的分叉情况会随着区块树的剪枝而被剪掉。

 

  客户当然希望双重支付(一笔钱使用两次甚至多次),所以,客户会制造出双重支付的交易来,那就应由柜员记账的时候把好关,但客户可能与柜员是同一个人(或合谋),因此,就有了我们先前的假设:守规矩的柜员的算力应大于50%,即在不信任的环境中要有足够的正义力量。

 

  前面说到守规矩柜员的职责:保证自己的交易链不分叉,他具体应怎么做?在记账(挖矿)时:

  •  对他人:一旦接收到的区块中含有双重支付交易,则不认可此区块(认为该区块不正确,不在该区块基础上挖矿);
  •  对自己:不将双重支付交易纳入区块中;

 

  要做到上述两点,则必须有一个检查双重支付的方法。

 

  上一节我们通过建立本地辅助信息库的方法,求出了区块链上各节点的高度。类比区块链与交易链的相似性,对比设计:

 

  区块链的表blocktab(KeyValuepreKeyHigh)

  交易链的表tran_tab(T_KeyT_ValueT_preKeyFlag)

  字段说明:

  •  T_Key:本交易的指纹即H(),作为键值
  •  T_Value:本交易
  •   T_preKey前置交易的键值(即指针,从IN中取出)
  •  Flag:标志本交易是否有后续交易,1为有,0为无

 

  类似于区块链表的High赋值,可以对交易链表的Flag赋值,交易存量表形成后,当该柜员收到一个新交易,则他可通过该交易的IN(指针)在交易表中找到其前置交易,若这个前置交易的Flag=1(即它有后置交易,表示已支付),则认为这个新交易是双重支付,直接抛弃(不允许分叉),否则则认可该新交易,即交易链长一节(新交易充当了该交易链中最右交易,此时,(1)新交易插入表中,其Flag=0;(2)将其前置交易Flag置为1,表示此时已支付)。当收到一个区块,则相当于收到了区块中所有交易,按上述方法逐个交易处理。通过Flag来检验,从而避免了双重支付。

 

  这里回答上节的思考题:为何不把区块在链中的高度写到区块头中?

 

  1、假定在区块头中有一个字段高度,你收到了该区块,你能填写这个高度么?不能,因区块是防篡改的。

  2、那这个字段只能在区块产生时填写,但由于长度(高度)优先的竞争,柜员有虚报高度的嫌疑,所以,也不能由柜员在产生区块时填。

  3、即使区块头中有高度字段且能保证它的正确性,查询起来也不方便,将这信息装入数据库,借助数据库的检索功能就方便了,就象图书馆中的书有编号,但还是要建一个图书管理系统。因此,区块在链中的高度由链自证,并显式化到辅助库中。

 

  同样的理由,可以解释这问题:为什么已支付的标志Flag不直接写在交易上,而要借助辅助信息库?

 

  6.3 避免双重支付(2)

 

  上述方案是在假定所有交易都是简单交易和币基交易情况下设计的,当取消这一假设时,交易为组合交易(即交易有一组IN和一组OUT,简单交易和币基交易视为其特例),通过类比的手法我们就可以建立预防双重支付的方案。

 

  从连接点上,我们有这样的类比:简单交易时,交易消耗掉一个前置交易交易中的指针指向前置交易”;而组合交易时,交易一个IN”消耗掉一个前置交易的一个OUT”交易一个IN中的指针(前置交易的指针+前置交易中OUT编号)”指向前置交易的一个OUT”。据此我们可以类比设计:

 

 

 

  1、简单交易时,是查前置交易,表是以交易为纪录;而组合交易时,是查前置交易的一个OUT”,故我们的表将以交易的一条OUT”为纪录单位(即表中的一行表示一条OUT);

 

  2、简单交易时,是查(前置)交易,故纪录以本交易的指针(指纹)为键;而组合交易时,是查(前置)“交易的一个OUT”,故我们的表中交易的一条OUT”的键为:本交易的指纹+OUT的编号。

 

  3、简单交易时,当前交易是对应于一个前置交易,一个T_preKey。而组合交易时,当前交易是对应于多条OUT”(源于不同的前置交易),即多个preHash || N*

 

  简单交易时:tran_tab(T_KeyT_ValueT_preKeyFlag)

  组合交易时,按前述办法,建立一个“OUT”表:

  OUT_tab(Hash || MT_ValuepreHash || N1preHash || N2Flag)

  OUT_tab中各字段的说明:

  •  Hash || N:纪录的键(交易的指纹Hash+OUT编号M);
  •  T_Value:该OUT所在的交易
  •  preHash||N1preHash||N2,:该OUT所在交易的所有IN指针,(个数是动态的,可设定一个最大值);
  •  Flag:该OUT是否被使用(即是否有一个IN指针所指向),若有,则标记该记录的Flag1;

 

  有了存量交易的OUT_tab表后,柜员处理一个新交易:对该新交易所有IN,查询对应的前置OUT,若有一个前置OUT记录的Flag1,则拒绝该交易,否则认可该交易,此时:(1)将新交易的所有IN(批量)指向的“OUT”纪录的Flag置为1(表示被此消耗);(2)将新交易的所有OUT(批量)插入“OUT”表中,且Flag都为0

 

  还有一个情况可放在交易的合法性中排除:新交易中有两个IN指向同一个前置OUT,即要求交易的IN组中指针不重复即可。

 

  §7 相关干系者

 

  本章从利益相关者的角度再来观察一下区块链技术。

 

  7.1 柜员(守规矩PK不守规矩)

 

  与守规矩柜员相反,还存在不守规矩柜员,它有两类:

 

  1、不作为的:他只顾自己挖矿,不去检验收到的区块和交易的合理性(从而节省了大量算力去算迷题),即他对共识毫无贡献。

 

  2、作恶者:他为某种利益,伪造、篡改交易或制造双重支付交易,将这些交易装入区块中,并希望通过共识算法,将该区块混进区块链中。但由于有守规矩的柜员的算力大于50%”的前提(严格讲,是守规矩的柜员用于共识的算法大于作恶者的),作恶者的区块一定会被剪枝。

 

  显然,守规矩柜员因为要保证链的正确性,所以需要做许多验证工作(不守规矩常没必要去验证)。总结一下守规矩柜员的工作:

 

  1、数据维护:同步区块和交易(逻辑上形成本地的区块链和交易池),构建和维护本地的辅助信息库;

 

  2、验证工作:在上述过程中,验证收到的区块和交易,即区块和交易是否是按规则组成的?是否是双重支付?并将验证结果存入本地的辅助库(避免反复验证,并供后续验证重用)。通常用辅助库和增量方式进行验证,如,前述讲过的双重支付检验方式,柜员保证:

  •  新交易内不冲突;
  •  新交易与你认可的链中的交易不冲突;
  •  新区块内所有交易与你认可的链中的交易不冲突;

 

  3、审计:即上述验证过程以及过程中运行交易验证脚本;

 

  4、参与共识:对通过了验证的区块,按共识的优先级,柜员认可区块(即以它为基础构建自己的区块);

 

  5、参与竞争:选择合格的交易,在上述认可的区块的基础上(利用其指纹)构建自己的区块,并解迷题,一旦解出就广播该区块;

 

  6、多线程工作:如,前述的矿池模式,有的线程也有强关系,如,同步线程发现别人也解出最新迷题,应通知解迷线程,及时中止本级迷题的计算,而改算下级迷题。

 

  算法并没有惩罚作恶者,而是奖励守规矩者。在激励政策下,作恶者会放弃作恶,因为,他的区块达不成共识,无利可图,所以,在技术和激励的双重作用下,作恶者被招安。

 

  从比特币的币基交易中,我们可知其奖励分为新币发行和手续费,而发行的总量一定(即一定时间后停止发行),当停止发行后,只有手续费奖励。竞争又使得柜员投入更多算力,即算力成本上升,若成本与手续费不适配的话,会导致柜员无利可投,则柜员(P2P节点)大规模退出,导致P2P网萎缩,甚至陷入瘫痪;成本若要与手续费适配的话,手续费又会上升到客户不可忍。解决这个两难问题只能是通缩,即手续费的数值未变,但价值(汇率)上升。通缩是由于限额发行引起的,反之,若不限额,则会产生通涨。关键问题是公众认不认这个通缩或通涨,公众的信心影响货币的价值,进而影响手续费的价值,再进而影响柜员的收益,从而导致柜员进入或退出该P2P网,在这个动态过程中,有可能打破守规矩的柜员的算力大于50%”的前提条件,这时作恶者可能会达成自己的非法目的。

 

  7.2 客户(付款人,交易者)

 

  客户(付款人)实际上是做交易者,他如何获取公有链的服务?有以下几种方式供选择:

 

  1、作为矿工(P2P上全功能节点或称验证节点),即他在该区块链的P2P网上既作为客户又作为柜员;

 

  2、作为单纯客户(P2P上非验证节点,简易节点),即在该区块链的P2P网上作为一个最小功能的节点,不参与柜员的工作,只能做交易,且本地下载的数据只与客户自己相关(俗称:钱包),如,区块链的区块头和含客户自己数据的残缺梅尔树;

 

  3、通过代理获取区块链的服务,这就有两层:(1)代理作为区块链的客户,按上述方式工作;(2)真正的客户使用常规的方式(如,用户和密码)在代理平台上注册,并只与代理平台进行交互。当然,他得信任代理(有的代理往往不可信),代理实际是交易平台或汇兑中心,如,比特币交易平台。

 

  对公有链而言,我们有时说交易能被跟踪,有时又说交易具有很好的隐私保护,这是怎么回事?

 

  1、我们知道有用户认证的系统在开户时,需要客户(身份)产生账户,再用密码将二者关联,也就是有客户、账户、密码三者及其关联,这就需要将其保存,以便核对,这个保存关联关系的库:一方面存在被泄漏的风险,另一方面使得系统知道了谁(客户)做了什么(即破坏了私密)。而公有链中,使用公钥地址作为账户,而用私钥代表客户(身份)和密码,这样使得(客户,账户,密码)三元组,变成了(公钥,私钥)二元组,而公、私钥二者本身又具有捆绑关系(密码学运算),不需要将对应关系存起来。即系统(1)不保存客户真实身份、(2)不保存客户的密码(私钥)。而是将保密性交给客户自己(即管理私钥),从而很好地保护了客户的隐私;

 

  2、而公钥地址(账户)和交易是全网可见的,因而又是可跟踪的,前述的交易链就反映了这一方面。但它只是跟踪到账户层面,而没有跟踪到客户层面。有时,客户与账户的对应关系又需要公开,如,公益组织的账户,它使得公益捐款情况公开透明。

 

  3、当然,大数据联合分析可以猜测客户,如,你用手机做了交易,通过手机实名或定位而确定客户,从而建立关系(公钥,客户)。另外,一个客户可以有多个公、私钥对,使得前述建立的关系,不能用于黑名单管理,因为你封锁了一个公钥,他可以再生成一个。

 

  总之,公有链中通过技术手段统一了透明和私密这两个极端情形:数据不加密和用公钥地址(大家都可跟踪)、私钥签名(交易真实)、指纹(防篡改)和与用户脱钩(保护隐私)

 

  当然,如果客户通过代理方式接入区块链,那么客户与代理的交互就是一个有用户认证的系统,从而破坏了公有链对客户隐私的保护。

 

  私密性使得金融交易对应的实际商务无法被审查等(抗审查性),这是比特币走红的原因(大量用于黑市和违法交易),同时,也是被政府抗住的原因。这种特性,因立场不同而表述成优势或劣势。

 

  考虑到法规和约束,可采取折衷方案保护隐私:在商业上使用半开放的分布式账本,即:使用联盟链,并建立用户认证体系,用户认证可以是中心化(独立于联盟链节点之外的一个认证中心),也可以是分布式(各盟管理自己的用户),这样,联盟链就实现了“KYC”(知道你的客户),这对于需要定位到的管控是必须的,如:打击非法交易、反洗钱以及相关黑名单管理等。

 

  7.3 客户(收款人,发货人)

 

  本节讨论作为公有链的收款人何时发货才无风险。

 

  假设客户(付款者)A是个作恶者,他可能制造双重交易(他可以提交成功,但未入账。设交易1和交易2A的双重交易),交易由柜员打包放入区块链中,守规矩的柜员在打包时保证自己的区块符合要求:

 

  1、同一区块中无双重支付问题:即上述交易1和交易2不会在同一区块中,这两交易中只能是其中之一被柜员认可,守规矩的柜员各自独立地保证自己的区块正确,但相互间呢?如,有柜员选交易1记账(包在区块1),另有柜员选交易2记账(包在区块2)。即两冲突交易可能会位于不同的区块中。

 

  2、区块间无双重支付问题:即上述交易1和交易2各自在一区块中时,这两区块只能是其中的一块被柜员认可。假定上述区块1和区块2都被广播,则区块1和区块2在链的不同(否则违反了这个要求),再由前面的共识机制的剪枝,一段时间(T)后,交易1和交易2只有一个被保留在区块链的长长的树干中,另一个成为垃圾交易”(它在被剪枝的垃圾区块)

 

  垃圾交易中包括两类:一是交易本身不合格,二是交易本身合格但在竞争中失去了资格(如,上述情况),网络中剔除垃圾交易也是需要考虑的(否则垃圾泛滥),方案上,可以设定时间上限(如,一天),当交易的发生时间超过了这个上限,则认为交易老死了,柜员不理它甚至在本地删除它。另外,由于区块的容量和产生区块的频度限制,在交易火爆期,会有大量交易积压,会造成大量非垃圾交易”“老死而不能记账。

 

  假定客户(付款者)A将资金转给B是为了从B处购买电子书,客户A做完交易1后,通知B,让B发送电子书,客户(收款者)B立即发货吗?交易1是转款给B的,上述双重支付中,一旦交易1在与交易2竞争时失败,则它成为垃圾交易,则B永远收不到交易1的款项,即造成了损失。

 

  所以,B不应该立即发货,而应等到足够时间后才发货,回忆时间与产生区块的关系,我们可定义交易被确认的次数为该交易所在的区块在区块链中从右向左数的序号,如,下图蓝色表示交易1,此时,说交易1被确认了三次。

 

 

  上述足够时间转换成足够的确认次数,此处的足够的确认次数是认为交易所在区块达到长长的树干的所需,比特币认为这个数为6,因比特币产生区块的频度为10分钟,假定交易能及时记账(从交易池到区块中),则B1小时(“足够时间”)后发货。类比传统交易,这个时间可以看作是交易的在途时间,真是近在咫尺”(P2P网已全网广播了该交易,它也在你身边),却远在天涯”(需要足够的时间到达共识状态)

 

  当然,在该交易1还是在途(如,交易1已在某区块中,而区块已在某分支上),这时B可以提交一个交易x将该资金转给X,回忆交易部分:客户是可以提交成功的,因此,应设法让其记账不成功,即对区块的正确性在上述两条上再加一条,并将检验的责任交给柜员:

 

  3、区块链中的先后关系不能违背交易资金流向的先后关系。

 

  在上述交易x能在交易1还是在途时提交的前提下,要求柜员在对交易x和其前置交易(交易1)打包时,两交易所在区块的次序应符合交易次序,即含有交易x的区块在含有交易1的区块的右边。

 

  实际上,从程序的角度可将上述前提改为更严格:交易x只能在其前置交易(交易1)已经在长长的树干上时才能提交。更进一步(资金在途不可见):付款方交易直到确认到长长的树干上时,收款方才能看到,如,交易1经过了6次确认后(即一小时后)B才能在其钱包软件中看到他的收款。这样,既能避免收款方提前发货的风险,又能避免收款方提前使用该款项(交易x)而不得成功的麻烦。当前,钱包软件是客户端的,作恶客户完全可以修改或重写,故前述的柜员检查责任还是不可少。

 

  总之,对收款方而言,资金的到达有一个在途时间,客户不能急着启动其后续动作,如,发货或转出该资金。我们曾说:区块链不支持强实时性应用(第四个缺点)

 

  7.4 构建者

 

  说公有链是完全去中心化的,也不对,实际上,系统的构建者(编程者)就是一个中心,构建者制订规则并以程序实现该规则,并发布和更新版本,相当于立法者,只不过执法者”(柜员或网络节点)不从属于中心化的组织,即俗称的去中心化

 

  构建者将系统程序开源,提升了公众对其信任度,公众亦可以对程序进行优化及维护,还可以抄袭。例如,你拿到一套区块链程序,进行抄袭修改,特别是对区块头的结构或内容进行修改(如,改为我在前面说的双指纹”),这样,你就得到了一部新,一旦你发布成功(足够的网络节点运行),则你就创建了一条新的区块链。比特币派生出大量的替代币,就是这样产生的。

 

  假如你的新法(新版本)兼容旧法(旧版本),即承认以前按旧法生成的区块,而新的区块按新法生成,则你的新区块链就可以在旧区块链上。但由于柜员是非中心化的,不一定听统一指挥,无法达到统一的版本升级,若理念冲突,则柜员就分裂为两部分:一部分仍用旧版本,他们产生的区块仍在旧链上成长;另一部分使用新版本,他们产生的区块却在新链(旧链的分枝)上成长,由于其兼容性(新链只认某个旧区块及以前的),这就产生了区块链的新、旧分叉(区块链的树主干形成“Y”型结构),这种分叉与前面讨论的分叉不同,它是有理根据的,是不可被剪枝的。为了区别,将这种分叉称为硬分叉,而先前讨论的分叉为软分叉”(它是树的顶端的分叉,且会通过共识机制剪枝)。例如,在对程序的升级版本中,若新版本动到区块数据结构改变,就会产生硬分叉,所以,在版本升级时要避免这种情况。这是区块链的第七个缺点。

 

  硬分叉使树的主干成“Y”字形(当然树的顶端又有软分叉”),这实际上形成了两条区块链,“Y”的左链和右链(“Y”的下半节公共),这时,会发生一个有趣的现象:当你有一笔资金在硬分叉前(“Y”的下半节)未使用,那么,硬分叉后,这笔资金可以在左链上和右链上各使用一次,也就是说:你的该笔资金一变二(但不能变为二以上)。你可用避免双重支付章节的内容来论证这一点。

 

  联盟链就不存在因升级而产生硬分叉问题,因为其柜员(网络节点)有限且可控。但会出现嫁接现象:若新版本动到区块数据结构改变,则树干的一段是桃树(由旧格式的区块组成),一段是李树(由新格式的区块组成),程序中要分别处理(if else)。另外,嫁接(新旧切换点)由程序写死。

 

  构建者的立法主要是针对柜员的入账(保证区块链的正确),提供样板程序和接口,而柜员和客户都可以修改非核心部分的程序,如,柜员可以结合特殊的硬件优化自己的挖矿程序、客户可以根据个人喜好美化自己的钱包。而作恶者若对进行非法修改,则得不到认可(作恶者的算力没有达到50%,这是公有链的前提)

 

  另外,作为应用级的程序员,虽不涉及上述的,但应注意:区块链的防篡改性会导致不能进行错误数据更改等维护处理。

 

  §8 区块链的商业应用

 

  本章从商业应用的角度来分析一下联盟链原理、效率及应用领域。

 

  8.1 联盟,共嬴的生态

 

  区块链分为三类:公有链、联盟链和私有链。公有链是区块链的发源地,前面已充分讨论。私有链我认为完成没必要,因为:它本身就是中心化的;即使有私有链还是要辅助信息库的,而在一个中心的前提下,后者可以取代前者。故此,本节我们重点讨论联盟链。

 

  大家说到区块链开口必是去中心化去信任化,那么,谁的?其实,是指去中介中心化去中介信任化中介在本文中就是指柜员,具体来讲,在公有链环境中,柜员不属于中心组织,客户不必信任柜员,当然,还是有一定的约束,即从总量上守规矩的柜员的算力超过50%

 

  区块链其实只是在这种无中心化无信任化中介环境中不得已而为之的策略,但其产生的技术可以在中心化信任化的环境中加以应用,因为,信息化发展到今天,已从昔日的信息孤岛,变成了信息中心林立,各自为王,商务流而导致的信息流(以及资金流、权益流)需要穿透各关联信息中心,这就需要一种破墙的信任机制,而区块链刚好从技术上提供了这种信任机制。即:通过联盟形成多中心的局面,而各中心间的信任,由区块链技术来保证。

 

  区块链技术提供了一种信任机制,具体包括:

 

  1、数据本身的可信:即,区块链记录的是交易明细,且是最原始的交易信息(源于客户提交的交易),柜员的作用仅是打包”(将交易装入区块中)。具体来说,是在交易数据本身正确(验证)的基础上,再通过数字指纹访篡改、数字签名访抵赖,这是以数学(密码学)为基础的。账务也通过指纹起来,来保证不被篡改,所以,区块链有个别名:(分布式可信)账本。

 

  2、数据存储的可信:即在线数据的容错/容灾,如,公有链通过全P2P网广播区块来保证数据的不丢失,而联盟链采取多写的方式来容错/容灾。

 

  3、账务的可信:账务是(交易)数据按一定逻辑要求组成的集合,如,不能重复记账、不能双重支付。在公有链上,柜员间不能协调记账,而是竞争记账,柜员间的分歧大,这就需要一个共识机制(前面大量篇幅就涉及这个复杂机制)。而联盟链则不同,联盟中各盟的数据中心就是柜员”(下面称为”),大家因信任而联盟,且个数少,有彼此信任基础,柜员间只需协调记账即可。故联盟链中只需协调机制,即:网络节点中按某种协议产生一个协调者(临时盟主),协调者按某种协调机制协调各节点记账,它包括两个方面:

 

    (1)按照一定的节奏构建区块链,区块链的特点是后一区块()含有前一区块()的指纹,故区块的产生是严格串行的,这对性能有一定的影响;

 

    (2)按一定的算法(协议),使分布式网络的数据达成一致(如,拜占庭容错协议)。其目的:一是通过同写来达到数据一致性;二是通过多写来容灾容错(存放在各盟节点);三是在同一时段中只有唯一的协调员(盟主),因此,不会发出再写指令,从而避免了重复入账,这里的数据有两个层面:交易和区块,其中交易可并行而区块必串行。将该协议在联盟链中的作用视为协调机制更恰当(类似于分布式数据库的数据一致性协议),当然,从商务宣传角度,挂上共识机制的大旗也未尚不可。

 

  基于联盟链的商务环境中,必须充当记账柜员,但它还可以充当客户的代理平台,即它是由两层信任组成:

 

  第一层是联盟链中各关联的间的信任,即从组织机构上,因信任而联盟,再加上从技术层面,区块链技术的信任机制使得盟间共享的数据可信。

 

  第二层是客户对联盟链的信任,这实际上又转移到客户对的信任,该信任实际又基于”(商户)的商誉,这主要是靠市场监管和声誉竞争来保证。客户有了对联盟链的信任,就可以以两种方式连入区块链:一是以作为自己的代理,二是自己作为链的非验证节点直接接入。

  反过来,联盟链也有要了解客户的需要,前面论述过“KYC”(知道你的客户),不再赘述。

 

  联盟链因有商业组织间的信任,故它在技术层面就可大大简化,如,共识机制简化为协调机制,因而提升了区块链的工作效率。

 

  商业运作通常会形成信息流、资金流、物流、资产流等,因而形成商业伙伴(如,各金融机构,供应链商家,监管及征信机构等),商业伙伴有着共同利益,从而可以结盟。从组织结盟,到技术结盟,结盟中利用区块链技术,象区块链一样紧密地联系、充分地共享,可共同建设新的商业生态。

 

  8.2 效率,不必纠结(1)

 

  前面已充分讨论过公有链的效率(比特币的记账时间为一小时),这里我们主要讨论联盟链的效率。

 

  根据前述的联盟区块链原理,我们可以设计一个等价的游乐场(如下图)来直观地分析交易记账效率:

 

 

 

  1、游客(对应于交易)在候车厅等待,交易是异步、批量处理的。为方便,假定游客到达是均匀的。

  2、打开检票队列,游客全部进入检票队列排队(设队列足够大,能容纳正在等候的全部游客),候车厅清空并关闭检票队列,后续到达的游客在候车厅中等待下一次检票队列打开。检票队列从关闭到打开形成一个时间窗口(记为)。则游客的均匀候车时间为

  3、检票队列的游客检票上车(对应于构建一个区块),为何只有一个检票队列?因为,区块的生成是串行的。记检票队列的游客全部检票上车的时间为 ,这里假定观光车足够大,能装完检票队列中的全部游客。

  4、游客乘坐观光车绕环形观光道进行观光(对应于该区块入账各盟节点,时间为 )

 

  5、多辆观光车,观光后回到起点,使保证已检票的游客不等车。

 

  根据此模型,我们分析联盟链的效率:

 

  一、呑吐率分析:

  1、区块链中的记账是批量的,可视为联机小批量”(控制区块链成长速度),批量时间窗口即为上述的 ,设交易均匀到达,则交易在批量窗口中的等待时间平均为 ;批量时间窗口 可以作为参数,根据应用进行调节;另外,可加一个类似人满开车的机制来应付高并发交易场景(如,平时五分钟一班”+高峰人满开车”),此时, 实际小于设定参数,即此时 由车的容量决定。为讨论最大呑吐率,我们设每次车满,即设每区块容纳的交易数为N,且每个批次的容量达到N

  2、构造新区块的时间,即为上述的 。联盟链不需解迷题,而且对交易的合法性检验可移到客户提交时做(因为盟节点的检验具有可信性),故仅为构造新区块的时间,主要是其中的构造梅克尔树的Hash计算。另外,由区块链特点可知区块是串行的。

  3、达成数据一致性的时间,即为上述的 。对于联盟链而言共识机制简化为协调机制(见上节描述),故 为协调多节点的写入区块的时间,是非常小的。

 

  综上所述,显然工作瓶颈在 ,又 ,为提升效率,让瓶颈处 处于连续工作状态,故可设: ,且 连续地串行。形成如下时序图:

 

 

  在上述时间片(两竖线间)3 ,期间相当于可完成3个批次的交易量(图中每种颜色的线段为三条),而前面已设每个批次的容量为N,故呑吐率为3N/3 ,即N/ (N为常数, 反映机器性能)。故在区块的容量N足够大时,呑吐率的瓶颈归于区块产生时间(检票时间)  ,这是区块链技术应用的代价:它的计算(花费时间 )是与交易本身没有关系,而是为保证交易不被篡改所做的加固工作。

 

  二、游客的时间花费(交易的记账时间)

  游客所花费的平均时间为 ,根据上述不等式,可以得到 ,即单个交易的瓶颈也在 ,而 一方面与区块中所含交易个数相关(当交易并发量不大时,区块链中梅克尔树小);另一方面与机器性能相关。

  综上,改善区块链的性能在于改善 ,而改善不能用并行策略(重要的事说三遍:区块的生成是串行的),只能靠提升算力,好在构建区块(含梅克尔树)的主要是大量的Hash运算,这种数值运算可以从硬件角度提升,如,用显卡或专门定制的卡,或开发专用的Hash运算机(类似于挖矿机)

 

  8.3 效率,不必纠结(2)

 

  上节我们重点分析了联盟链的交易记账效率情况。

 

  再看交易的查询:前述我们已经用本地辅助库的方式来改善查询,即不是直接查区块链,而是查辅助库,故在此前提下,不存在区块链对查询效率的影响。

 

  最后,看看客户的交易提交:对于公有链,客户的交易提交与柜员的交易记账是彻底的异步,而对于联盟链,虽然二者也是异步,但客户与柜员(盟节点)可以有些交互,如,客户提交的双重支付,柜员可以通过本地辅助库的协助检查,返回错误。即许多对交易的合法性验证可以放在这个环节,即不在记账时间的 中。如果异步反馈客户,将交易提交成功,就视为交易成功,则会大大提升客户的性能感受。事实上,在大多情况下可以这样做的。但对于该交易关联的后续处理而言,还要再等到记账时间之后。

 

  上述我们对效率情况进行了分析,区块链不是万能的,因此,我们不必纠结效率,在选择区块链的应用时,应尊重客观存在性,避开效率问题,从而找到适合的应用。

 

  我认为从效率角度应考虑这两方面约束:

 

  1、寻找符合区块链交易特点的应用。区块链本质上,对客户而言是异步(微观角度);对柜员而言是联机小批量,即一次一区块(含一批交易),当然,交易并发量少时,会导致中只有很少交易,甚至只有一个交易(区块中只装一个交易)

 

  2、避开区块链交易的瓶颈。上述记账时间T类似于资金的在途时间,如果急着用,则不适合区块链。如,(国库券等)额度抢购的应用,额度就是急着用的。

 

  8.4 应用,不断探索中

 

  许多区块链应用其实是利用区块链数据的严谨性,区块链数据的严谨性体现在如下三个方面:

 

  1、交易端:数据有客户签名,防假冒、防抵赖;

 

  2、路途中(包括:跨空间的传递和跨时间的存放),区块有指纹,防篡改;

 

  3、整链有历史,区块中含有时间戳(time stamp)

 

  目前,许多基于区块链的应用基本上是传统平台应用的移植,选择那些切合区块链优势(基于上述严谨性,)和避免区块链劣势(实时性性能不高)的应用,就是考虑关键。下面举几个应用区块链特色明显的应用方向:

 

  1、转账汇款,有两种方式实现转账汇款:

 

  (1)利用公有链的转账机制,如,比特币本身可以转账,对法币则:汇款方在比特币交易平台上通过法币买入比特币,将比特币转给收款方,收款方卖出比特币。当然,这种方法有一定的汇兑损益。一段时间该方法成了资金外逃工具或其它非法活动,现已被监管机构注意。

  (2)利用区块链传递电子汇款单,如,联盟链中,盟中心与区块链互动:汇款银行系统扣除客户金额,生成电子汇款单,收款银行签名领取电子汇款单,并将资金入自己系统的客户账。

 

  2、与时间相关的存在性,利用区块的指纹和时间戳证明事件存在的时间域。

 

  (1)时间点前。如,将你的一张照片放入一个交易中,交易又在区块中,则可以证明这张照片所提供的信息是在生成该区块之前,而该区块上又有时间戳。

  (2)时间点后。如,上述照像中,你拿着一张写有某区块A指纹的纸,则可说明你是在区块A的时间戳之后照的。

  (3)时间区间。上述两项联系起来,就可以得到事件发生的区间,当然不是精确的,而一定是正确的。

 

  3、公证与私证应用。电子记录由于其易修改性,司法上一直难以令人信服。而区块链中所存入的内容不被篡改,可以应用于证据保全领域。

 

  (1)将原始记录存于区块链中,以保证后续司法活动中不被篡改。

  (2)将区块链作为重要活动的记录本,可直接从中提取证据。

 

  4、通过智能合约与物联网、产权流转等联姻。

 

  (1)基于区块链中的加工和物流信息用于产品跟踪。将各环节的摄像或重要资料置于区块链中,生产商、分销商、消费者以及监管部门共享信息,形成基于区块链的供应链生态。如,钻石行业的追踪,钻石基本参数、外形照片、特殊标记等作为跟踪信息,流转环节通过交易实现,并有参与者的签名。

  (2)智能合约自动进行资金支付和产权交接。即:将合同电子化和程序执行化,如,电子签名、自动流转与自动执行等,并与合同对应的系统进行互动。比如,你的购房智能合同(含按揭),自动执行中涉及付首期、按揭审批与贷款发放、物权变更等,合同正常流程之后,使用你智能手机中的智能钥匙即可打开房门。而对违约也能自动走到扣违约金甚至进入司法程序等。

 

  综上所述,我罗列一些区块链可能的应用领域如下,你认为哪些应用适合于区块链?

 

  1、利用区块链的各方信任的严谨数据,建立具有跨界工作流性质的交易应用,如,供应链上交易、产品跟踪、产权流转、转账汇款、审批流程;商务事务(物流、税务、海关、银行互联流程)

  2、利用区块链数据的可信、共享特点,建立可供多家(或共众)共享的信息应用,如,医疗与健康信息、公益、办公信息、征信信息、电子书等分享。

  3、利用区块链交易签名所具有的防假冒、防抵赖以及历史性(时间戳)等特征,提供具有公信力性质的应用,如,专利与版权、司法证据、以及各类登记管理并形成电子证书(如,产权登记、合同、身份证、毕业证等)

  4、利用区块链提供的签名和可信机制,杜绝萝卜章事件发生,如,将其应用于交易合同、票据、金融产品(如理财产品、股权、债权)等,相关方可查、可验,防诈骗、防虚假。并且可作为内部风险防范措施,可极大地减少内控、审计和监管成本,如,抽查指纹就可以判别一批交易中是否有交易被柜员修改。

 

  结束语

 

  日常生活中,我们也可以找到区块链的影子,如,某人说:他是张三丰的第100代传人,其包含的信息是:张三丰是创世纪代,每一代将其基因DNA(类似于区块链中的指纹)传给下一代,到了他这一代是第100(类似于区块链中的高度)。你可能说,这是一颗家族而不是一个,其实,我们稍加限制就可以得到:假定张三丰有一本武功秘笈,作为掌门人的标志,只传给长房(类似于区块链中的优先权),而张家太极宫又有一规矩,当掌门人的旁系分支疏远到一定程度就要整个分支搬离太极宫(剪枝),这样,太极宫历史不就是围绕武功秘笈的一条了吗?这条历史链承载着历史:它的信息是可自证的,如,说张某人是张三丰的第100代传人,则要从张三丰算起,直到他来查验证。显然他是骗子,因为,从人类繁衍(区块链产生)的速度来看,目前不可能到100代。但若每次碰到宣称时都要从头验,则没有效率。故要有效率地复述历史,可将区块链隐性的信息显性化,这就是借助辅助信息库来有效地讲故事。当然,要使你讲述的故事可信,就必须加入某种信任机制(共识)

 

  终于完成了区块链之旅——我学习和欣赏了区块链中的相关思想,并以通俗化的方式总结成文。作为一个算法爱好者,在行文过程中,更多的视角是基于程序员关注的算法,其细节部分也渗入了自己的一些想法,不对的地方请大家指正。

 
 
企业简介 | 版权声明 | 免责声明 | 频道介绍 | 安全提示 | 法律顾问 | 网上投稿 | 客服电话 | RSS订阅
Copyright © 2005 Fcc.Com.Cn, All Rights Reserved. ,《中国金融电脑》杂志社版权所有
电话:010-51915111-805 传真:010-51915236,网络出版服务许可证(署)网出证(京)字第337号
京ICP备14024077号-1 京公安网备:11010802025321 技术支持:站多多