VeChain:解读唯链白皮书之唯链雷神区块链
前言:
唯链(VeChain)项目启动于2015年,致力于秉承"为协同而生"的理念,利用区块链+物联网技术打造信息透明、协同高效、价值高速传输的可信任分布式商业环境。
作为全球领先的企业友好型区块链公链平台,唯链自主设计开发的雷神公有链平台(VeChainThor Blockchain)具备完善的经济模型和强健的治理架构,确保区块链技术在合理落地的同时为企业以及个人提供便简易捷且安全可靠的区块链全套解决方案。
目前,唯链已在6个国家及地区设立分公司和办事机构,包括中国上海,中国香港,日本东京,法国巴黎,新加坡及卢森堡。已携手我们的战略合作伙伴普华永道(PwC)和挪威船级社(DNV GL)与多家不同行业的领军企业建立合作关系。合作伙伴包括宝马汽车、雷诺汽车、光明集团、D.I.G.、德铁信可(DB Schenker)等。目前唯链团队拥有超过90名专业人员,2018年底预计将扩大到至少120人。
主讲人简介:
周子衡,唯链首席科学家,拥有英国南安普顿大学计算机博士学位。先后以研究员和资深研究员的身份任职于英国肯特大学和芬兰奥卢大学,参与了欧盟和芬兰科学院重要科研项目,拥有十年计算机科研研发以及在国际一流学术杂志和会议上发表科研成果之经验。
周子衡博士于2017年加入唯链,主要负责唯链雷神区块链的科研研发及知识产权保护等工作。
分享主题:
解读唯链白皮书之唯链雷神区块链
内容看点:
以下为直播分享内容实录:
大家晚上好,我是唯链的周子衡,在唯链大家都叫我老周。首先,感谢硅谷密探组织这次活动,让我有机会和大家分享一下唯链雷神区块链白皮书里的内容,也感谢大家抽空来参加这次活动,这次主要是解读白皮书中关于区块链底层技术的内容。
我今天主要讲四方面的内容,首先是对我们新的白皮书做一个简要介绍,然后讲一些技术方面新开发的内容,包括多方支付协议,交易模型以及权威证明(PoA)共识机制。
首先简要讲一下唯链的新白皮书,关心我们唯链项目的伙伴肯定已经注意到,5月份我们更新了白皮书,本次白皮书一共114页,主要讲了我们唯链团队在过去一年内方方面面的进展,包含项目的背景、我们团队对未来的规划、社区治理模型、通证经济模型、雷神区块链、雷神区块链平台架构和服务以及应用案例介绍。
在进入具体的基础细节之前,先讲一下今天讲解的大纲。首先我会从现实中遇到的问题入手,逐步引出我们的解决方案。目的是告诉大家为什么我们要做这些事情。如果大家对具体细节感兴趣的话,可以去研究我们的代码和白皮书。也欢迎大家能加入到我们的技术开发社区中,为提升雷神区块链,做出自己的贡献。我在每个章节也会放上相应的代码路径,大家感兴趣可以去看一下。
多方支付协议
首先对于多方支付协议,我们具体遇到什么问题呢?
对于一个普通的用户或者一个传统企业来说他要使用去中心化的应用,也就是人们常说的DApp,其实是一件不容易的事情。大家在刚接触区块链的时候都深有体会,你要去学习如何使用数字钱包?如何来获取数字资产?如何来使用和管理数字资产?都需要大量的学习时间。
对于一个对区块链没有太多认知的一个普通人来说,他需要对区块链有一个较深的理解,才能更好地使用这些工具来帮他管理数字资产。而对于传统企业来说,他们都看到了区块链对企业发展能起到的作用,也愿意使用区块链来开发DApp以转型传统业务,从而改善经营活动。
对于这些企业来说,他们面临的问题其实是一样的,即如何管理数字资产?如何获取数字资产?如何面对数字资产在现有市场上的不确定性?这对传统企业来说是一个非常大的挑战。我们与很多企业的接触中了解到:他们愿意使用区块链,但是他们需要有一个非常可控的预算来帮助他们管理企业、运作企业。但在现实生活中,对数字资产来说,给出一个可控的预算,其实是一件很困难的事情。
不管是对普通用户还是传统企业来说,他们遇到的问题可以归结为:交易的支付问题,即如何来支付交易费?因此我们从底层架构上设计了多方支付协议,来帮助大家解决这个问题,从而降低使用区块链的一个门槛。
下图显示了我们多方支付协议的三个层级。在唯链雷神区块链里,当一笔交易发送到链上,在执行这笔交易的时候,我们引入了授权账户的概念,我们的区块链会首先看一下这个交易的发送方是否为目标账户的授权账户,假设这个目标账户是一个智能合约地址,如果是授权账户的话,交易费就可以从这个目标账户里扣除。
同时我们又引入了赞助人账户的概念,即每人都可以有一个赞助人账户来赞助交易的目标账户,或者说赞助这个智能合约。任何交易费用,都可以先从赞助人账户中扣除,如果赞助人账户里没有余额了,那再从交易的目标账户中来扣除,如果交易的目标账户中也没有余额了,最后才从交易发送方的交易账户中扣除这笔费用。大家可以在Github上runtime目录里面的resolve-tx.go中的BuyGas函数里看到我们这个支付逻辑的代码。
对于一个企业来说,它的账户在雷神区块链上的支付逻辑,就是下图的拓扑结构。其中包含了这个企业的智能合约账户、使用智能合约的用户账户、赞助智能合约的账户、还有一个主人账户。我们可以看到,每一个合约它都可以有自己的用户,每个合约都可以给不同用户授权。这些用户在使用合约的时候,它的交易费用就由这个合约来支付。
当然,用户也不能无限次地让合约替他支付,合约有权设定规则限定用户的使用频率和使用用量。我们可以看到每个账户还可以有多个赞助人,这个赞助人的概念在实际中是怎么用的呢?其实就是企业可以有很多的合作伙伴,有一些合作伙伴对数字资产的管理能力比较强,企业就可以让这些管理能力比较强的合作伙伴来协助他管理DApp,这些赞助人的账户可能就是他合作伙伴的账户,或者说是其他有能力管理数字资产的人的账户,这是赞助人和企业也可以签订一些常规的协议,来满足各方的需求。
谈到这个主账户,大家知道一个企业做DApp,可能包含了很多的合约账户,对于每个合约账户来说,分别操作它们并设置用户。对于企业来说可用性非常差,所以我们引入了这个主账户的概念。每一个合约账户都可以指定一个主人账户。主人账户可以代替这个合约账户管理用户(新增或删减)、设置规则并指定某个用户如何使用它们的服务。另外它可以同时拥有多个赞助人,并帮助合约来选择当前使用哪一个账户来支付调用合约的交易费用。
大家从上图就可以看到,企业使用我们多方支付协议,就可以有很多种管理账户的途径,它可以用一个主人账户来管理多个合约账户,帮助用户使用它的合约也就是使用它的DAPP。
对于用户来说的话,他们其实不需要考虑数字资产,只要他们是授权用户的话,他们就可以直接去使用这个DApp,从而大大减轻了他们使用DApp的门槛。下图列出了和多方支付协议相关的一些代码的路径,大家有兴趣的话可以去看一下。
交易模型
接下去我们来讲一下唯链雷神区块链里面的交易模型。我们对于以太坊的交易模型,做了比较大的变动,主要是为了解决以下四个问题:交易发送的并发性的问题、交易本身的效率问题、交易的时效性问题以及交易之间的依赖关系的问题。
对于每一个区块链网络来说,它都必须要解决一个问题,那就是防止重放攻击的问题。那什么是重放攻击呢?重放攻击是指同一笔交易被重复的广播使用。以太坊通过账户加上一个Nonce的整数变量来解决这个问题。具体来说当一个账户发送一笔交易的时候,这个账户里对应的Nonce变量就会被递增,同时Nonce值就会被写到交易里。当以太坊的结点来验证这笔交易时,它就会对比这个交易中的Nonce和账户中的Nonce,来确保不被重放攻击。
虽然以太坊解决了这个重放攻击的问题,但也带来了交易并发性的问题。举个例子:假设一个工厂里生产出十件商品,那这十件商品都要去区块链里面去注册信息。对于这个车间来说,它会发送十笔交易,那很有可能十笔交易都是由同一个账户来发送,如果其中的一笔交易没有发送成功的话,因为这个Nonce设置,在它之后发送的交易都不会成功。所以我们引入了交易ID的概念,每一个交易都可以计算出一个唯一的ID。
这个ID是怎么计算的呢?下图列出了交易ID的计算方法。首先,我们会把交易数据的签名去除,再对去除之后的交易数据进行哈希,将之后的哈希值和发送的地址方进行连接,最后再对整个的数据进行哈希来产生我们最后的交易ID。
我们在交易模型当中,也加入了Nonce的变量,那这个变量可以怎么来用呢?我们可以通过简单的改变Nonce的变量来产生不同的交易ID。对于这个工厂来说,它其实只要不停的递增Nonce,也就是,每次都递增Nonce,把这个Nonce写进它发送的交易里面,那这些交易它所对应的交易ID都是不一样的,所以这些交易不管先后顺序,它们都会被我们的雷神区块链结点验证,并且执行。另外,这个Nonce,除了可以用来产生不同的交易ID之外,还可以用来证明计算量,来提高交易的优先级,具体可以去读一下我们的白皮书和开源代码。
大家都知道区块链是一个异步系统,也就是说用户和区块链进行交互的时候,有很多的因素会影响用户发送交易的状态。有时候大家会希望给不同账户转账的操作可以同时被执行,但现在的以太坊是做不到的,如果要确保这些交易是否被成功执行的话,需要去跟踪每一笔交易,确保它最终被执行。其实这就是交易的效率问题,为了解决这个问题,我们引入了子句结构。下图显示了这个字句结构的定义。可以看到每一个子句它都包含了三个变量。其中,从上到下就是一个to变量,交易的目标地址,value代表所要转帐的数额,data为附带的一些数据。对于一个交易来说,它包含了一个子句的序列,这个序列里可以包含多个子句。也就是说,只要交易的发送方是同一个地址的话,它可以包含多个子句来发送交易给不同的地址。这样交易的效率可以大大提升。我们不用再去同时跟踪多笔交易,我们现在只要做的是把原本的交易变成子句写进同一笔交易内,然后跟踪这笔交易即可。
从这样的一个设置里就可以看到我们雷神区块链交易的另一个性质:交易内子句的原子性。大家都知道区块链的交易是有原子性的,也就是说,要么被执行,要么不被执行,所以让交易内包含了我们子句的序列,也就代表了我们这些子句的执行是有原子性的,它们要么全都被执行要么就全都不被执行。
同时还有一个特性,在我们的算法里面,当我们执行子句序列的时候,这些子句就会严格按照它的交易顺序来执行。也就是说,你把子句写入的顺序即这些子句被执行的顺序。举个例子,用户可以在同一个交易里面先创建智能合约,然后再对这个合约发送交易,来确保对于合约的操作发生在合约创建之后。
接下来讲一下交易的时效性问题。我想大家接触区块链时间久了都会遇到以太坊拥堵的时候,这种发出去的交易不能被执行也不能被取消,就眼睁睁的看着它在钱包里呆了两三个小时,为什么呢?因为在以太坊里我们无法控制交易的时效性,无法控制它在多长时间内是有效的。但在雷神区块链里,我们对交易模型做了相应的调整,使我们可以控制交易的时效。我们主要是加入了两个字段,一个是叫Expiration字段,以区块为单位,定义当前交易的有效期,另一个就是叫BlockRef字段,它包含的是一个区块的ID,它定义的是,每笔交易的起始点,就是它最早可以被打包到哪一个区块当中。
大家可以看到下图这个代码显示的是一笔交易,它在验证过程中的一些代码。第一个红框就可以看到我们会对比检当前的区块高度和这个交易的BlockRef所对应的区块的高度。如果发现当前的区块高度比BlockRef指定的交易区块高度低的话,也就是这是一笔未来要发生的交易,系统不会执行那这笔交易,会返回consensusError(共识错误)。第二句判断的就是这笔交易是否已过期,Expired这个交易能够被打包的最后一个区块的高度,如果发现当前的区块高度已经大于最后指定的能被打包的区块高度的话,系统就会返回一个共识的错误。
大家可以看到其实我们可以通过这两个变量来决定这笔交易最早被打包的时间和最晚被打包的时间,也就是说我们可以决定这笔交易在什么时间段内是有效的,在时间段之外,还没有被打包的话,那这笔交易就被废弃无法再被执行了。
大家可以回想一下以太坊账户里Nonce的设定,虽然说这个Nonce的设定影响了账户发送交易的并发性,但是它也有一个好处,就是它内在的定义了交易的依赖关系,也就是说由这个账户发送的交易,Nonce小的交易必须在Nonce大的Nonce之前来执行,所以就自然而然的产生一个依赖的关系。但这个依赖关系,其实有一定的局限性,也就是这个依赖关系只存在于由同一个账户发送的交易当中。但这个性质其实是很多开发人员都想使用的。
那我们怎么来解决跨账户的交易之间能不能有依赖关系的问题呢?为了做到这一点,我们在交易模型里面加入了DependOn字段,这个字段包含的就是一个交易的ID。通过这种方法,我们可以显性的表示交易与交易之间的依赖关系。在交易时我们在DependOn放一个交易的ID,这笔交易,它的这个执行依赖于交易ID所对应的交易的执行情况。这里需要提出,我们规定之前的这笔交易必须要被执行成功。
什么叫执行成功呢?就是在以太坊的EVM虚拟机执行这个交易的时候并没有报错。其实这一点比较关键,因为一笔交易被打包,并不代表它被正确的执行,有可能因为种种原因,比如交易的gas不足、发送交易账户的余额等其他原因使它未被执行。所以,我们在这里加入了需要交易执行成功这样一个额外的条件,使得依赖关系的可用性更高。
下图代码显示的就是我们在验证这笔交易的时候,验证这个DependOn的过程。大家看到这个过程,首先是通过found函数去查找DependOn对应的交易ID是否存在,查找的结果返回有三个值:第一个值,代表这个交易是否存在,第二个值代表这笔交易是不是成功被执行;第三个值是错误查找过程中的错误信息。
所以看到在函数执行没有错误的情况下,它会先判断这笔交易是不是已经找到了,如果没有找到,那这个交易ID对应的交易没有找到,那这个系统ID就会返回一个共识错误。第二个就是说,如果这个交易就是说,没有被正确执行的话,系统也会返回一个共识错误。
下图包含了刚刚所说的所有内容的一些代码的路径。
权威证明(PoA)
最后,给大家讲一下我们唯链雷神区块链的共识协议或者共识算法。我们用的是权威证明的共识算法,英文就是Proof of Authority,在说共识算法细节之前,我谈一下个人的一些看法。一个区块链的共识算法它其实是区块链上的治理模型的直接表现。它是整个区块链开发团队,对区块链的治理理念的一种表现。这个权威模型也体现出我们团队对区块链治理的理念。大家也知道在区块链上所谓的权力,最重要就是记账的权力,也就是产生新区块的权力。在权威证明里面,一个节点想要获得记账权的话,它必须要向唯链基金会提出申请,唯链基金会会对持有这个节点的个人或者机构进行审核,评估一下这个个人或者机构是否会对雷神区块链的发展有贡献,最终如果通过我们的KYC的认证过程,并且持有我们一定量的数字货币的情况下,基金会会给他颁发记账权。
大家在讨论共识算法的时候无非会提出三个问题:第一个问题就区块在什么时候产生的?第二个问题是由谁出来产生区块?第三个问题就是,如果节点遇到两个合法区块的时候,如何判断哪一个是主干上的区块?
对于何时出块的问题,其实答案也很简单,雷神区块链上规定每隔十秒出一个块。为什么选择十秒钟呢?那是基于我们团队对于区块链的使用量来决定的。
第二个问题是由谁来出块?首先出块人必须是基金会已认证的节点,我们现在统称为记账节点,然后再决定由哪一个记账节点在这个时间出块?具体来说,由谁出块是由三方面因素来决定的,也就是区块的高度加上区块出块的时间再加上当前活跃记账节点,我们之后会对活跃记账节点进行详细的描述。我们记账节点是怎么计算出来的呢?首先是我把区块的高度和区块的时间进行连接之后,算出它们的哈希值,这个哈希值会对活跃记账节点记账数目取模,取模以后得到一个值。对于所有活跃记账节点,它们是以一个固定的顺序排列的。所以我算出这个值之后,就可以从活跃记账节点中选出对应的记账节点来,赋予它出块权。
现在给大家讲一下活跃和不活跃是怎么来理解。对于一个记账节点来说,它有两种状态,一个是活跃的状态,一个是不活跃的状态。当一个记账节点,它被授权之后默认的就是一个活跃的状态,代表他是会出块的,大家默认它会出块。当然一个记账节点可以由活跃变为不活跃,怎么看待这个问题呢?假设我是一个节点,这个节点当前的区块高度是n-1,当前的区块时间是t1,下一个区块收到之后时间是t4。那中间t1和t4之间不是隔着10秒而是隔着30秒,这代表着什么呢?代表中间有两个记账节点应该他们出块而它们并没有出块。所以我在验证这个区块高度为n的区块时,就会计算在t2和t3这个时间点应该是由哪两个记账节点来出块,它们并没有在出块,所以我会把它们的状态设为不活跃。这时记账节点的状态就发生了改变。
相反一个记账节点下线后,肯定会被其他记账节点认为不活跃,那怎么从不活跃变为活跃呢?首先,我会先同步最新的区块,在这个基础上,我会不停的计算下一个时间点是不是我出块。当然在计算的过程中,我是默认自己的状态是活跃的。如果下一个时间点轮到我出块了,我就出一个块,把这个区块广播到网络当中。当其他节点收到我做的这个区块之后,大家会验证这个区块,一旦大家验证完这个区块是合法的,那这个区块对应的状态数据库里,大家就会把我的记账节点的状态从不活跃设置成活跃。如果我出的块又被大家认为是主干上的区块,那我的活跃状态就会一直保持下去。
最后一个问题,如果我同时接收到两个合法区块时,如何判断哪一个是主干上的区块?哪一个是枝干上的区块?我们的做法是通过累积活跃记账节点数量来做出决定。也就是说,假设当前区块的父区块里,记录的是之前所有的累计活跃记账节点数量,那我现在当前的记账节点累计的数量就是由副区块中累计的数量加上过程中我看到活跃的记账节点数量。在比较过程中,我们首先比较的是两个区块当中累计的活跃记账节点的数量,我们认为数量大的区块是主干上的区块。如果这两个区块上累计的活跃记账节点数量是相同的话,那我们认为区块高度低的是主干上的区块。这个权威证明的代码是在sched.go这个文件里面,大家如果感兴趣的话,可以去看一下。
问答环节:
Q1:交易过期这个时间是多长呢?怎么考量的?
答:这个期限是由用户自己来定的。用户需要定的是这个交易的起始打包的区块高度再加上这个交易它在多少块之内它是有效的。
Q2:唯链为什么不从新开发一条公链,而是从以太坊上面分叉侧链,想请问一下如果唯链上面的企业,用户和dapp增多,是否网络延迟?
答:我们PoA里的激励机制是这样的,一个区块里所有的交易它消耗的VTHO百分之三十会返回给出块的记账节点。首先声明一点:我们唯链是一条新开发的公链,只是说我们用了以太坊的一些基础的服务。比如说是以太坊的虚拟机服务,用了一些以太坊的默克尔数的包,其他的代码我们都是自己开发,考虑到效率问题以及我们加入的一些新的特点,所以它严格意义上不能算以太坊上的分叉链吧,更不能说是一条侧链。
我们认为完全重写代码的想法本身是不成熟的,也是不符合事物发展规律的。项目的代码质量好不好,主要是看它有没有新的思想,而这个新思想有没有对于区块链这个样也做出贡献。特别对于开源项目来说,开源本身它的目的就是希望能有更多的项目在我的基础上做的更好。我们的目标是把项目做的更好,所以我们希望能站在巨人的肩膀上开始。这样我们的起点更高,走也更远。
Q3:该出块的节点没有出,这个问题怎么处理?
答:该出块的节点没有出的话,那在这个时间点上,就会没有区块。
Q4:唯链TPS是多少?哪些参数或者因素影响TPS?
答;我们目前TPS是设置在50,其实这个系统的TPS可以被提升,但是考虑到现在的用量,我们认为50已经够现阶段使用了。其实我们最高可以达到10000TPS,在未来都是可以实现的。
Q5:节点不出块后被标记为不活跃,下一轮出了会变为活跃,,如果他一直不出怎么办,其他节点计算自己什么时候出块,需不需要考虑那些不出块的节点? ? ?
答:如果一个节点在该它出块的时间没有出块,那其他记账节点都会标记该节点为不活跃的,所以下一次计算由谁出块时将不会考虑这个不活跃的记账节点。
Q6:交易打包后需要经过多少区块确认之后才算成功?
答:其实要从理论上回答这个问题,我们就要考虑有什么样的攻击方法来攻击我们的这个区块链网络。我们自己也做了一些研究,从我们自己构建的概率模型上算出来,其实在等12个区块之后,受到攻击的概率就非常小了,现在来说,我们为了安全可能还会多等几个区块。
Q7:请问溯源防伪中不论是使用芯片还是其他的什么技术,始终都会与奢侈品保持一定物理距离, 换而言之,这种芯片与奢侈品的联系是可以被解除的,那么怎么保证防伪呢?
答:这个问题我想可以从两维度来考虑。从区块链技术本身来说,区块链本身它不提供直接防伪的作用,它提供的是分布式的账本,大家可以把一些数据记录在这个账本上,记录的东西是不可篡改的、公开透明的。防伪就是另一个维度的考量了,就看链下的技术怎么来保证放在区块链上的信息,能够和真实世界的物品进行唯一的绑定。这方面的话还是需要更多的研究。
Q8:我转账的时候看到过19/12确认,就是多等几个区块确认这个意思咯?
答:你说的没错。
我今天的分享就到这边了,非常感谢大家,也欢迎大家在我们雷神区块链上进行一些科学的研究。