孙林昆,蒋文保,郭阳楠,李春强
(北京信息科技大学 信息管理学院,北京 100192)
区块链由于其去中心化、防篡改和可追溯等特点,引起了金融机构、投资机构、监管部门以及政府部门的广泛关注。但目前区块链仍存在较多技术难点,如性能问题就是其中之一。区块链在不同场景下的应用都因高冗余存储增强了数据的公开性、透明性和去中心化,提高了系统的可用性;但另一方面,每个节点都需要同步并保存系统中所有的账本数据。此外,共识节点为了验证交易,需要存储账户余额以及系统中各种智能合约的当前状态,这使得参与共识协议的成本更高,也给区块链带来性能问题和巨大的存储压力。
针对上述问题,许多学者进行了大量研究。与传统的存储方案不同,比特币[1]采用一种SPV 的方式缓解存储问题,但随着存储量的增多,会有更多的节点无法承担全节点的存储需求,从而转变为轻节点,降低网络的去中心化程度。文献[2]通过IPFS协议将交易存储进链下,链上保存交易的索引,该文主要针对基于UTXO 模型的区块链设计,未考虑基于账户模型区块链的存储及智能合约执行情况。文献[3]通过分片技术降低了单个节点的存储负担,同时提高了区块链系统的吞吐量,然而该系统中的跨分片交易存在分叉攻击的威胁,并且该系统需要执行一个代价高昂的节点重新分配协议,以增强系统安全性。文献[4]提出在 DHT 网络中验证新交易和新区块以保存区块链数据,然而该系统需要频繁访问网络来申请状态数据,并且不具有数据缓存功能,具有较大的网络开销。文献[5]采用纠删码的方法有效降低了系统中区块数据的冗余存储数量,然而共识节点在执行交易时需要进行频繁的网络请求来恢复区块数据,给网络带来一定的负担。
近年来,无状态区块链的概念[6-7]被提出,无状态区块链通过减少节点的状态数据存储量从而减少存储负载。然而,现有的无状态区块链系统[7-8]大部分是为加密货币设计的,而试图开发支持智能合约的通用无状态区块链将面临新的问题。首先在一般应用程序中,由智能合约支持的事务可能包含任意逻辑,这需要新的证明技术来证明合约执行的完整性;其次智能合约交易会引入任意大小的读写集,这比简单的加密货币交易复杂得多,需要额外设计来支持状态承诺更新[9]。
本文提出一种基于密码累加器的无状态区块链性能优化方案STiPChain。采用RSA 累加器生成具有分布式存储能力的合约有效性证明(Contract Validity Proof,CVP)技术,并基于该技术构建无状态区块链,共识节点不再保存区块数据,而只需保存合约累加值及合约有效性证明降低磁盘和内存的负担。在此基础上,STiPChain 将有效性证明与可验证计算技术相结合,设计一种适用于智能合约的无状态区块链,以解决无状态条件下智能合约运行验证问题。
以Ethereum[10]为代表的区块链2.0 是基于交易的状态机,从创世区块开始,通过交易持续不断地改变区块链状态。区块链状态信息描述了系统中账户和余额的当前状态,以及在区块链虚拟机中部署和运行的所有智能合约的参数数据。链上每个最终确定的区块都有且只有一个状态,这是由网络中的所有参与者共同确认的。每当有新的区块产生时,系统状态都会随之更新。
在无状态区块链中,用户和共识节点都不需要存储完整的系统状态。相反,所有账户的当前状态以及在EVM 中部署和运行的所有智能合约的集体组成的状态使用经过验证的数据结构在所有节点中分配。通过这种方式,共识节点只存储系统状态的简要摘要,每个用户存储他们的自身状态数据。共识节点仍然可以验证收集到的交易,这些交易中包含了合约的有效性证明。此外,共识节点仍然可以提出新的事务块,用户也可以在发布新块时快速同步或更新他们的证明。
文献[11]提出一种基于RSA 累加器的改进型轻节点,极大地优化了轻节点的存储空间,但是并没有解决全节点存储问题。文献[12]基于RSA 累加器提出一种适用于UTXO 模型的无状态客户端,可以较好地优化共识节点的存储问题,但并不能适用于智能合约的验证。文献[6]提出一种无状态交易验证的通用框架EDRAX,所有节点只需持有最新被确认的区块即可验证交易并更新状态,但是EDRAX 仅支持对账号的余额进行验证。文献[7]首先针对通用累加器和向量承诺,提出了批处理技术,极大地提升了累加器的验证效率并降低了传输开销。然而,该累加器只适用于基于UTXO 模型的无状态公有链,同时在不知道群阶的情况下,RSA 累加器批量删除操作的复杂度为O(n2),导致累加器更新效率低,无法适用于高吞吐量的环境。文献[8]通过KZG 多项式承诺[13]构造新的向量承诺方案aSVC,使用一个更强的交叉承诺聚合概念,将不同向量承诺的多个子向量证明聚合为一个单一的、恒定大小的证明。该方法虽然可以高效地支持加密货币转账交易,却不能支持智能合约所需的任意计算逻辑。
可验证计算技术[14]确保远端计算机计算行为与期望一致,同时确保任意参与者可以检测和监视整个过程,可验证计算通常由基于密码学和基于硬件2 种方式实现。以SNARKs[15]为代表的基于密码学[16-17]的可验证计算技术由于密码原语的存在,通常具有较高的计算量。相比之下,基于安全硬件的解决方案效率更高,如以Intel Software Guard eXtension(SGX)[18]为代表的可信执行环境(TEE)[19],可以将计算任务在可信执行环境中以保证数据完整性的方式执行。
文献[20]提出将计算与共识解耦,计算节点在线下的TEE 环境中完成隐私数据的计算,并向区块链提供正确计算的证明。共识节点维护区块链账本以及验证计算节点计算的正确性,将可信执行环境和区块链相结合,实现了高效的隐私数据处理。
本文主要考虑使用基于TEE 的解决方案,TEE提供了一个完全隔离的环境,可以防止其他软件应用程序、操作系统和主机所有者了解甚至篡改在TEE 中运行的应用程序的状态。例如SGX 提供了TEE 的实现,Keystone-enclave 项目[21]旨在提供开源TEE 设计。然而,值得注意的是:本文提出的性能优化方案可以与上述任何可验证计算解决方案共同工作。
STiPChain 将传统区块链中共识节点存储系统中的全部智能合约的状态数据转变为存储各合约的有效性证明,将智能合约的状态数据抽象为hash 摘要,并通过RSA 累加器完成各智能合约摘要的累加与合约有效性证明的创建。同时,各节点不必存储所有智能合约的有效性证明,而是可以根据节点本身需求存储相对应合约的hash 摘要及有效性证明,从而极大地降低系统及系统中单个节点的存储量。
此外,STiPChain 将区块共识与区块执行解耦,由提议节点执行合约事务并生成交易,共识节点负责提出区块共识与新区块。用户在提交交易时,首先由提议节点在本地可验证计算环境中执行智能合约,之后采用Remote Attention 机制对TEE 进行认证,系统中任意节点可以检查提议节点是否正确地加载了智能合约与合约参数以及运算结果完整性的验证。共识节点基于合约有效性证明生成技术快速验证合约状态摘要的合法性,并通过Remote Attention 机制验证智能合约的执行情况,从而解决智能合约在无状态环境下的验证问题。可验证计算确保了智能合约在提议节点本地得到了正确执行,共识节点不再需要在区块链虚拟机中执行智能合约字节码完成系统状态更新,而只需要更新合约有效性证明即可完成,从而有效提高系统吞吐量。
1)提议节点:接收用户交易请求,在本地TE 环境中运行智能合约并在交易中附上可验证计算证明,使得共识节点可以在不保存合约状态信息的情况下完成交易执行的验证。
2)共识节点:运行共识协议并维护区块链全局状态的一致性。接收提议节点在区块链网络中广播交易并存储至交易池中,从交易池中打包一批交易组成候选区块进行检查与执行,并提出新的区块。
STiPChain 系统架构如图1 所示。
图1 STiPChain 系统架构Fig.1 STiPChain system architecture
密码累加器技术由文献[22]提出,目的是证明一个元素是否存在于集合中的问题。它将集合中的元素X={x1,x2,…,xn}累加到一个值AAcc上,并为各元素生成存在性证明π,从而可以通过(AAcc,xi,πi)快速判断元素存在性问题。当前很多学者基于不同的密码工具给出了不同的构造,可分为基于RSA 的累加器、基于双线性映射的累加器和基于Merkle 树的累加器[23]。
合约有效性证明(CVP)基于RSA 累加器设计,重要符号说明如表1 所示。在CVP中,Alice 存储n个元素xi的一个恒定大小的累加值AAcc。元素xi本身不是由Alice 存储,而是分配给n个参与方,除元素xi外,每一个参与方都持有对AAcc的证明πi。当Alice 希望通过u′更新合约状态u的累加元素时,其应该能够通过仅访问信息(u,u′)轻松地将AAcc更新为A′Acc。也就是说,与Merkle 树不同,更新是独立于其他元素的。类似地,当参与方i得知更新(u,u′)时,应该同样能够有效地只通过访问(u,u′)更新证明(πi→)。
表1 符号说明 Table 1 Description of symbols
CVP 非常适合区块链中的智能合约模式,共识节点存储各合约的有效性证明累加值AAcc,每个智能合约有效性证明用πi标识,通过(πi,xi,u,πTEE→u′)的交易形式标识一条智能合约xi从状态摘要u改变状态到u′。在检测πTEE是合法的情况下合约状态证明更新πi→,同时共识节点更新AAcc→,以便将累加值包括在新区块,使得所有其他提议节点同步它们的相应证明πi。
借鉴文献[7]中的RSA 累加器设计,将累加器建立在未知阶的群上,避免进行可信的初始化设置。通过参数λ,生成累加器初始值g,并随机挑选2 个大素数p、q,生成N=p×q。
提议节点将创建合约的请求打包进交易中发送至共识节点。设Acci-1为创建此合约时系统中保存的最新累加值。此时,Acci-1中不包括当前要创建的合约的状态摘要。基于RSA 累加器特点,由RSA 累加器AAcc计算式(1)及证据计算式(2)定义得累加器中元素i的有效性证明,可由除i之外的其他元素集合来表示,因此合约xi的有效性证明可由Acci-1表示,通过文献[24]完成hash 转为素数。
当系统发布新区块时,共识节点需要更新累加值AAcc,同时各提议节点需要完成其保存的合约有效性证明πi的更新。由于在不知道群阶的情况下RSA累加器更新合约有效性证明的时间复杂度为O(n),而CVP 基于区块链的区块特性以及状态驱动特点,使得合约有效性证明更新的时间复杂度降低为O(1)。在区块链中,每当系统发布新的区块时,各节点都需要接收该区块并同步更新自身合约有效性证明。获取合约i更新后的状态摘要u′,通过式(3)将AAcc更新到,合约有效性证明通过式(4)更新至。
该方法可以有效防范恶意节点通过合约历史有效性证明πoldi发起双花攻击。当产生新区块后AAcc→,若恶意节点将πoldi作为当前合约的有效性证明,则根据式(5)及hash 函数的抗碰撞性,恶意节点很难成功发起双花攻击。
共识节点需要完成合约状态证据的合法性验证。{0,1}←WitAccVerify(AAcc,π,u):验证者使用合约有效性证明累加值AAcc检查合约状态u的证据π是否有效。若等于AAcc,则表示证据有效输出1,否则证据无效输出0。
STiPChain 实现了由传统区块链中共识节点冗余存储各合约的状态数据转变为保存各合约状态证明,提议节点在TEE 中运行智能合约,共识节点检查交易可验证计算证明πTEE,从而使得各节点无须运行智能合约,也可以完成全局状态的更新。
本节介绍共识节点如何在不保存状态信息的情况下完成交易的验证与执行,以及如何在区块链网络中保持状态信息的一致性。STiPChain 的交易处理流程如下:
1)用户通过提议节点发起交易请求
2)提议节点接收到交易请求后,提取本地状态摘要、要执行的智能合约及相关参数,转发到TEE 中进行计算,获取交易读写集及改变后的合约状态摘要。
3)执行完成后将可验证计算证明、交易读写集及本地当前合约状态摘要(u,u′)嵌入该交易中,将交易进行广播发送。
4)共识节点接收候选交易,存入交易池中。满足交易阈值后将交易池中的交易打包为候选区块。在创建新区块时,每个区块头除了包含交易的Merkle 树根外,还包含了由所有智能合约状态组成的CVP 累加值。当新区块产生后,需要向CVP 中添加区块中新的合约状态,构造新的CVP 累加值。经过相应的共识算法后发布新区块。
5)提议节点接收新发布的区块,并更新本地CVP 承诺以及合约有效证明。
交易流程如图2 所示。
图2 STiPChain 交易流程Fig.2 STiPChain transaction procedure
为了提供足够的信息用于共识节点在无状态环境下的合约验证,提出一种新的基于TEE 的交易生成算法。如算法1 所示,它接收2 个输入:1)来自用户的交易请求txi;2)用户对交易请求的签名sign。
当提议节点发起交易时,首先在TEE 环境中执行交易所调用的智能合约,将生成的读写集写回数据库并重新计算此时的合约状态摘要。此外,将提议节点中保存的合约状态ui,以及更新后的合约状态′ 一并通过Remote Attention 机制进行签名,用于防止节点恶意篡改合约数据以及系统中其他节点对数据完整性的检查。将运行后的结果打包进交易并广播发送给共识节点。
算法1提议节点交易执行
共识节点完成区块创建工作,在创建区块时首先通过Remote Attention 机制验证该条交易的可验证计算证明。若验证通过,则证明该交易被正确执行,即修改后的合约状态可信,完成该条交易验证。共识节点重复n次,完成区块中所有交易的验证,根据相应的共识算法发布区块,并将该区块添加到本地账本中,其余节点同步更新本地合约状态摘要。提议节点验证通过后,从交易中取出合约状态hash,通过CVP 验证合约状态摘要是否合法。引入缓存,使得交易可以在接下来的k个区块时间内被处理,避免因为网络延迟导致的交易验证频繁失败的问题。k是一个系统参数,由系统中的所有参与者共同制定。
假设最后一个被计算的是blockt,而共识节点竞争的是blockt+1。共识节点收集新交易并打包为候选区块,采用算法2 生成新区块。在blockt+1中,需要包含新的累加值。其中,txs表示共识节点从交易池中打包的一批交易,h表示当前系统中的区块高度(输入)。算法流程如下:检查该条交易是否属于最近的k个区块;解析交易并检查sign 是否为该用户下的有效签名;检查πTEE是否为可验证计算的有效签名;检查πi是否为合约xi的有效证明,其中为区块t的合约累加值;将AAcc更新参数放入缓存,该区块验证结束后进行更新并填入新区块,同时节点可根据自己需要完成对智能合约i的证据更新。
算法2共识节点交易验证
Alice 在接收到新区块后,运行区块中的数据并更新本地合约有效证据。πi是合约xi的本地状态证明,它对应到blockt之前的合约状态。当系统中发生了新的交易并且创建了blockt+1时,系统的世界状态发生改变,Alice 的本地验证πi不再有效,持有合约xi的节点必须同步新的证明,以确保它包含所有更新。blockt+1中包含新的合约状态(u1,′),(u2,u′2),…,(ui,)。为此,Alice 通过运行π←WitAccUpdate(AAcc,ui,N)并执行算法3,输出一个新的同步验证。Alice 从blockt+1中进行同步,基于Remote Attention 机制和本地存储的合约状态πi确保合约状态进行正确的更新,然后更新本地证明。需要注意的是:Alice 在进行同步时运行与共识节点交易验证相同的算法来验证区块合法性并完成状态同步。此外,各提议节点并不需要保存系统中所有合约的有效性证明,可根据节点自身需求保存相应合约的有效性证明。
算法3提议节点合约有效性证明同步
本节量化了STiPChain 每种优化的性能收益,测试了CVP 证据大小和CVP 更新效率以及系统吞吐量和节点的存储开销,评估了STiPChain 的5 个应用,1 个同台加密计算合约,并通过Solidity 语言实现链上的基于同态加密的加减运算。ERC20 转账操作、链上文件保存操作、数据加密和链上明文计算5个合约运行在EVM中。与Ethereum 主网相比,STiPChain 可以在定长时间内完成交易验证及状态证明更新,支持吞吐量更高、存储量更低的合约运算。表2 所示为STiPChain 与其他区块链优化方案的对比,其中:√表示是;×表示否。
表2 STiPChain 与现有区块链优化方案的对比 Table 2 Comparison between STiPChain and existing blockchain optimization schemes
将区块链系统部署在4 台阿里云ecs.c7t.large 服务器,每台服务器运行4个节点,配置Intel Xeon(Ice Lake)Platinum 8369B 处理器,内存为4 GB,网络带宽为10 Gibit/s,安装Alibaba Cloud Linux 操作系统。
本节主要完成不同状态承诺技术的证据大小测试。实验结果如图3 所示,Boneh、Edrax 及STiPChain 的合约有效性证明大小随着累加元素的增多一直维持在1 KB左右,不随累加元素的增多而增大。然而,Merkle 树产生的证据大小远大于Boneh 及STiPChain,并且随着累加元素的增多以lbN的增长速度增大,当累加元素个数为10 000时,证据大小达到了626 KB。Ethereum 普通区块包含一个区块头和交易列表,其大小约为100 KB,这种大小可以使得区块广播速度较快。但若采用Merkle树承诺方案会对网络带宽带来较大负担,系统中网络延迟较高。
图3 合约有效性证明大小测试结果Fig.3 Test results of contract validity certificate size
本节主要测试合约有效性证明的更新效率,该效率直接影响了系统的吞吐能力。Boneh 使用RSA 累加器构建 UTXO 承诺,承诺更新的时间复杂度为O(n),Edrax 基于向量承诺方案实现更新操作的时间复杂度为O(lognlog logn),而STiPChain 基于区块链的全局状态一致性,只需要进行添加操作即可完成合约的有效性证明更新,更新时间复杂度为O(1)。
图4 所示为STiPChain、Edrax 与Boneh 累加器的更新效率对比。Boneh 更新时延随着累加元素的增多明显增高,当累加元素个数为1 600时,更新时延为17 033 μs。Edrax 方案随着累加元素个数的增多增长缓慢,当累加元素个数为从100 增长到1 600时,更新时延从83 μs 增长到152 μs;STiPChain 的更新时延不随元素个数的增多而增长,维持在24 μs 左右。实验结果表明,CVP 更新时延最低,而Boneh 累加器更新时延远大于STiPChain 与Edrax,并且随着累积状态数量的增多明显增高。当操作数量达到1 400时,Boneh 累加器更新时间是CVP 的16 000倍,这就导致依赖于Boneh 状态承诺的无状态客户端设计面临严重的性能问题。
图4 合约证明更新效率测试结果Fig.4 Test results of contract certification renewal efficiency
本节主要评估系统的存储开销,分别测试了Ethereum Geth 模式下全节点、文献[4]及STiPChain 中状态数据的空间开销。获取了Ethereum从20190101—20220101 期间运行全节点所需存储空间的数据变化(https://etherscan.io/chartsync/chaindefault),并与文献[4]和STiPChain 进行对比实验。此外,本文将缓存参数k设置为16,可保证大多数交易被处理。
图5 所示为状态数据存储开销对比,Ethereum 在20220101已经超过了1 TB 并以极快的速度继续增长。在20190101—20220101 期间,文献[4]共识节点存储量由17 743 553 KB 增长到89 506 154 KB,通过采用分布式哈希表的方法有效降低了节点的存储负担,但仍然远高于STiPChain。相较于Ethereum 中全节点需要保存全部的区块数据及状态数据才可验证与执行区块中的任意交易,STiPChain 中共识节点保存AAcc,所占存储空间不到1 KB。获取要验证交易中包含的合约有效性证明π,通过交易验证算法即可完成交易验证与状态更新,从而有效降低共识节点的存储需求。此外,通过仅存储AAcc完成交易验证,使得系统中的状态存储空间不随运行时间的增长而明显增长,从而降低共识节点99%的存储压力。
图5 存储空间优化测试结果Fig.5 Test results of storage space optimization
截止到20201006,以太坊中已经包含了31 949 110条智能合约以及87 570 650 条用户地址信息。虽然STiPChain 将共识节点中的区块及状态数据采用合约有效性证明标识,并将合约有效性证明的存储负担转移至提议节点,但对于整个系统来说,提议节点并不需要存储全部智能合约的有效性证明,而是根据自身的需要存储,从而降低系统中数据冗余程度。与Ethereum中全节点数据完全冗余方式相比,STiPChain不仅可以有效降低共识节点的存储负担,并且可以有效降低整个系统的数据存储量。
为了测量STiPChain 的峰值性能,本文对16 个客户端进行了实验,每个客户端向一个计算节点发送100 个串行请求。测试采用共识节点执行交易所需时间作为吞吐量测试样本,并对每条合约实验忽略测试起始与结束前10%的请求,测试平均稳定的性能。图6 所示为吞吐量测试结果。STiPChain 的吞吐量一直高于2 000 T/s,各合约之间吞吐量变化不大。Ethereum 在ERC20 转账合约中达到了1 619 T/s,而在Encryption 合约测试中仅有67 T/s。实验结果表明,STiPChain 相较于Ethereum 具有更高的吞吐量并且在处理复杂合约时更具有优势。STiPChain 中的共识节点在修改全局状态时只需要检查合约有效性证明和可验证计算证明,无须重复执行交易,通过该方式可以有效地提高系统的吞吐量。
图6 吞吐量测试结果Fig.6 Test results of throughput
针对多数公有链低吞吐和数据增长问题,本文提出一种基于密码累加器的无状态区块链性能优化方案STiPChain。STiPChain 通过CVP 状态承诺和可验证计算技术将状态和交易执行转移到提议节点,共识节点负责交易验证及区块提交,从而提高系统的可扩展性。在此基础上,设计了新的状态承诺方案以及链外事务执行、链上事务验证和节点同步方案来支持无状态交易执行与验证。实验结果表明,相较于Etherrum,STiPChain 能够极大地降低共识节点的存储压力,并有效提高系统吞吐量。下一步将利用安全多方计算[25-26]技术实现RSA 累加器的可信初始化设置等关键功能,并通过状态承诺[27-28]模型给出安全性更高的状态承诺方案,从而提高的系统安全性与运行效率。