摘要:NULS,让区块链更简单!
为什么要有账本模块
在区块链中,由全网节点共同记录并保持一致的资产/数据往来,我们称之为交易,而根据交易对每个账户所做的资产/数据统计结果构成了账本。所有账户的余额都保存在账本中。每一个全节点中,都会保存一个完整的全网账本,保证了数据的完整、公开、透明,同时也保证了数据的不可篡改。
NULS2.0是一个面向定制化服务的区块链基础设施,采用微服务架构,根据区块链系统的业务,将底层拆分成不同的模块。账本作为区块链的核心组成部分,有许多通用的功能,在NULS2.0中,我们将账本相关的功能拆分出来,单独组成一个模块,可以很好地为系统提供记账、查账、验证等服务。
在NULS2.0中,账本模块是数据中枢,保存系统内所有账户的余额,它不依赖任何业务模块,其它模块按需依赖于它。
账本模块功能
账本模块功能体现了该模块的作用,也是开发该模块需要达到的目标。读者阅读本文档的目标是理解账本模块具有哪些功能,以及这些功能的实现流程。
对于账本模块来说,其自身只有更新账本这一个主要功能,其他都是通过接口对外提供的数据查询服务。
但是由于区块链是去中心化的网络环境,部分节点有作恶可能,发起双花交易。为了防止双花交易,账本模块在保存账户余额的同时,还需要维护一个跟账户关联的交易随机数(nonce)。
账本模块保存账户余额的功能并不难理解,反而是交易随机数(nonce),需要理解其设计原理,下面,我们先针对交易随机数(nonce)做一些介绍。
交易随机数(nonce)
首先,通过交易随机数(nonce)能避免双花,是因为交易随机数遵循以下原则:
同一账户可以同时拥有多种资产,每种资产对应一个nonce值;同一账户同种资产发起的交易,对应的nonce值,必须是连续的。
正是通过nonce值的连续性,有效地避免了双花交易。假设网络中,有人从一个资产余额为10NULS的账户,向两个不同的地址分别转账5NULS,正常情况下,两笔转账之后,该账户的余额应该为0,但是此人发起的是双花交易,想要在转账之后,仍然保留5NULS的余额。
由于nonce值必须连续,两笔交易的nonce值如果连续,两笔交易就会被先后确认,该账户的资产余额,在账本中会经过两次更新,最后变成0,从而避免双花;当两笔交易的nonce值相同时,两笔交易就不会被打包在同一条链中,会形成分叉链,最终被打包在最长链中的交易,将会被保留,而另一笔交易则会被丢弃,从而避免双花。
未确认交易的nonce值
由于在许多业务场景中,需要在短时间内连续发起多笔交易,所以在NULS2.0中,为了满足这样的业务需求,交易模块允许在短时间内,连续发起多笔交易,这些交易在未被确认之前,会缓存在未确认交易池中。但是未确认交易的nonce值,依然遵循上面提到的原则,从而避免双花,保证交易的正确性。
锁定资产维护
在创建节点、委托挖矿等业务场景中,需要对资产进行锁定,我们可以把这样的交易理解为锁定资产交易。在NULS2.0中,因为资产锁定之后,想要解锁,是根据对应的交易一笔一笔解锁的,所以账本模块会为每个账户维护一个锁定资产表格。
这个表格存储了每笔交易nonce值哈希的后8位,以及每笔锁定资产交易锁定的金额,这样通过账本中记录的账户余额和锁定资产金额,就可以知道该账户的可用资产是多少。当用户解锁资产时,根据nonce值哈希的后8位,就知道解锁的是哪一笔交易对应的资产。
账本验证
当用户发起一笔交易时,交易需要在账本模块中进行验证,验证的流程如下:
用户发起交易,交易验证环节发起账本验证请求;账本首先对交易nonce值进行验证,如果验证失败,返回验证不通过,验证成功,进入下面的流程;账本对交易中账户的资产余额进行验证,如果验证失败,返回验证不通过,验证成功,代表账本验证成功。
更新账本
账本的更新是从发起一笔交易开始的,为了便于理解,我们列出整个交易的主要流程:
用户发起一笔交易,账户模块对交易进行签名;系统对交易信息进行验证,包括基础验证和业务验证;交易管理模块将交易存放到未确认交易池中,等待确认;交易被广播之后,被打包进区块,区块需要进行验证;区块验证通过,交易得到最终确认,交易管理模块存储交易数据;账本模块根据交易,更新账户对应的余额和nonce值。
其他
账本模块启动时需要依赖的模块
账本模块在启动时,可以不依赖任何模块。