区块链Fabric 账本、链码和节点数据交互步骤、通道、节点
1、账本
账本结构由一个区块链构成,并将不可变的、有序的记录存放在区块中;同时包含一个状态数据库来记录当前的状态。其中区块链结构保存在本地的文件系统中;世界状态由数据库来维护,以键值对(k-v)的方式保存在数据库,默认数据库为LevelDB,数据库版本可替换为KV类型的数据库,如CouchDB等。
账本结构如下:
区块链(Blockchain):
区块链(Blockchain)是基于本地文件系统,将区块存储于文件系统的硬盘中,每个区块中保存有区块头(Block header)、区块数据(Block data)、区块元数据(Block metadata),通过区块头中的前一个区块的哈希值(Previous Block Hash)指向前一个区块的当前哈希值(Current Block Hash),连接成区块链。
上图中区块图示说明:
B:Blockchain 区块链
B1:Block 区块
H3:Block header 区块头
D1:Block data 区块数据
T5:Transaction 交易数据,保存在区块数据中
M3:Block metadata区块元数据
H1-H2:H2 is chained to H1 区块2指向区块1
状态数据库(State Database):
状态数据库是存储所有在交易中出现的键值对的最新值,调用链码执行交易可以改变状态数据,为了高效的执行链码调用,所有数据的最新值都被存放在状态数据库中;状态数据库被设计为组件,可以通过配置替换数据库,目前有LevelDB和CouchDB两种数据库, LevelDB是默认的内置的数据库。
LevelDB:适用于简单的链值对k-v场景,LevelDB嵌入在peer进程中。
CouchDB:适用于支持丰富的查询和数据类型的场景,应用系统作为JSON文档存储时,CouchDB是一个特别合适的选择,支持对chaincode数据进行丰富的查询。
2、链码(智能合约)
智能合约又称为链码,是在区块链上运行的一段代码(实现具体业务逻辑),是应用系统与区块链底层交互的中间件,通过智能合约可以实现各种复杂的应用。目前使用Go语言来开发智能合约以外,还可以使用java、node.js开发,支持最好的还是Go语言。智能合约安装在节点(Peer)上,运行在Docker容器中,通过gRPC与Peer进行数据交互,交互步骤如下:
1) 链码(chaincode)调用 shim.Start()方法后,给节点(Peer)发送 ChaincodeMessage_REGISTER 消息尝试进行注册。客户端链码等待接收来自节点(Peer)的消息。此时链码(chaincode)和节点(Peer)的状态为初始的created。
2) 节点(Peer)在收到来自链码容器的 ChaincodeMessage_REGISTER 消息后,会注册到本地的一个handle结构,返回 ChaincodeMessage_REGISTERED 消息给链码容器。并且更新状态为 established ,然后会自动发出 ChaincodeMessage_READY 消息给链码(chaincode),并且更新状态为ready。
3) 链码(chaincode)在收到 ChaincodeMessage_REGISTERED 消息之后,先不进行任何的操作,完成注册步骤。更新状态为 established 。在收到 ChaincodeMessage_READY 消息之后再更新状态为 ready 。
4) 节点(Peer)发出 ChaincodeMessage_INIT 消息给链码容器,对链码进行初始化。
5) 链码容器收到 ChaincodeMessage_INIT 消息之后,调用用户代码 Init()方法进行初始化,成功之后,返回 ChaincodeMessage_COMPLETED 消息。到此,链码容器可以被调用了。
6) 链码(chaincode)被调用的时候,节点(Peer)发出 ChaincodeMessage_TRANSACTION 消息给链码。
7) 链码在收到 ChaincodeMessage_TRANSACTION 消息之后,会调用 Invoke()方法,根据Invoke方法中用户的逻辑,可以发送如下的消息给节点(Peer):
ChaincodeMessage_GET_HISTORY_FOR_KEY
ChaincodeMessage_GET_QUERY_RESULT
ChaincodeMessage_GET_STATE
ChaincodeMessage_GET_STATE_BY_RANGE
ChaincodeMessage_QUERY_STATE_CLOSE
ChaincodeMessage_QUERY_STATE_NEXT
ChaincodeMessage_INVOKE_CHAINCODE
8)节点(Peer)在收到这些消息之后,会进行相应的处理,并回复 ChaincodeMessage_RESPONSE 消息。最后,链码(chaincode)会回复调用完成的消息 ChaincodeMessage_COMPLETE至节点(Peer)。
9) 上述消息交互过程完成后,节点(Peer)和链码(chaincode)会定期相互发送 ChaincodeMessage_KEEPALIVE 消息给对方,以确保彼此是在线状态。
3、通道
通道是两个节点(Peer)或多个节点之间信息通信的私有空间,在通道内的交易的数据与通道外隔绝,保证通道内数据的安全。在网络上的交易都要在某个通道(Channel)上执行,参互交易的每个成员都需要进行身份验证和授权,才能在通道(Channel)上进行处理。
Fabric是多通道设计,系统可以创建多条通道,某个节点(Peer)可以加入到不同的通道中,在每个通道中有自身的创世区块和实例化智能合约(Smart contract)。
每个通道都有属于自己的锚节点,通过锚节点可以与其它通道进行信息交互,但本身通道内的账本不会通过一个通道传到另一个通道上,通道对账本是分离的。
通道结构图:
上图中通道图示说明:
N:Blockchain Network区块链网络
节点(Peer)是区块链的交易处理和账本维护的主体,主要负责参与共识过程和通过执行链码(chaincode)实现对账本的读写操作。节点(Peer)根据功能不同分为背书节点(Endorser peer)和提交节点(Committer peer);根据通讯不同分为锚节点(Anchor peer)和主节点(Leading peer)。
背书节点(Endorser peer):背书节点(Endorser peer)负责对交易根据事先设定策略进行签名背书,背书节点(Endorser peer)根据链码在实例化的时候设置背书策略,指定哪些节点用于背书。当客户端向节点发起交易背书时,该Peer节点才雎有背书功能,其它时间只是普通的记账节点。
记账节点(Committer peer):记账节点(Committer)负责维护状态数据和账本的副本。
锚节点(Anchor peer):锚节点(Anchor peer)是随通道(Channel)存在,是能被其它通道发现的的节点(peer),每个通道(channel)上有一个或多个锚节点(Anchor peer)。
主节点(Leading peer):主节点(Leading peer)负责与排序(Orderer)通信,把共识后的区块传输到其他节点。
应用程序与节点交互图:
C:Channel 通道
P:Peer 节点
S:Chaincode 链码
L:Ledger 账本
A:Application 客户端
PA-C:Principal PA(e.g. A,P1)communicaties via channel C 客户端A与节点P(Peer)通过通道C(channel)进行通信。
H1-H2:H2 is chained to H1 区块2指向区块1
4、节点
节点(Peer)是区块链的交易处理和账本维护的主体,主要负责参与共识过程和通过执行链码(chaincode)实现对账本的读写操作。节点(Peer)根据功能不同分为背书节点(Endorser peer)和提交节点(Committer peer);根据通讯不同分为锚节点(Anchor peer)和主节点(Leading peer)。
背书节点(Endorser peer):背书节点(Endorser peer)负责对交易根据事先设定策略进行签名背书,背书节点(Endorser peer)根据链码在实例化的时候设置背书策略,指定哪些节点用于背书。当客户端向节点发起交易背书时,该Peer节点才雎有背书功能,其它时间只是普通的记账节点。
记账节点(Committer peer):记账节点(Committer)负责维护状态数据和账本的副本。
锚节点(Anchor peer):锚节点(Anchor peer)是随通道(Channel)存在,是能被其它通道发现的的节点(peer),每个通道(channel)上有一个或多个锚节点(Anchor peer)。
主节点(Leading peer):主节点(Leading peer)负责与排序(Orderer)通信,把共识后的区块传输到其他节点。
应用程序与节点交互图:
上图中通道图示说明:
N:Blockchain Network区块链网络
A:Application 应用程序
P:Peer 节点
S:Chaincode 链码
L:Ledger 账本
O:Orderer 排序
交互流程(比较笼统,其中涉及到背书节点等):
1)应用程序成功连接到节点(Peer)后,调用链码向节点(Peer)进行提案;
2)节点(Peer)根据提案信息调用链码;
3)链码进行查询和更新,然后返回提案信息给应用程序;
4)应用程序发送交易信息给排序(Orderer);
5)排序(Orderer)把含有交易信息的区块发送给节点(Peer);
6)节点(Peer)把交易区块更新到账本中,最终完成处理;