Michael.W谈hyperledger Fabric第24期-详细带读Fabric的源码9-peer节点有关账本的重要接口

Michael.W谈hyperledger Fabric第24期-详细带读Fabric的源码9-peer节点有关账本的重要接口

1 PeerLedgerProvider接口-账本操作

Fabric账本存储的接口定义在core/ledger/ledger_interface.go文件中:

	type PeerLedgerProvider interface {
		// 账本的创建。会为一个已给出的创世区块创建一个账本对象
	  	// 该方法将保证利用创世区块来创建账本是一个原子操作。
		Create(genesisBlock *common.Block) (PeerLedger, error)
		// 打开一个已存在的账本
		Open(ledgerID string) (PeerLedger, error)
		// 判断账本ID对应的账本书否存在
		Exists(ledgerID string) (bool, error)
		// 列出当前Peer节点所持有的账本列表
		List() ([]string, error)
		// 关闭账本
		Close()
	}

PeerLedgerProvider的接口功能与orderer节点的Manager接口十分类似,作为一个功能上的封装。

2 PeerLedger接口-账本查询

账本ID:是一个字符串,同时它是由创世区块指定下来的。创世区块中还包含一些属性来标识这该账本的一些特性。

Fabric中账本是按照通道进行隔离的,也就是说一个通道就会有一个账本。

并且一个账本中会对应三种数据:

  1. 账本数据
  2. 状态数据
  3. 历史数据

通过账本ID打开一个已存在的账本,将返回一个PeerLedger对象:

	type PeerLedger interface {
	  	// 账本的文件存储
		commonledger.Ledger 
	// 下面四个get方法是关于区块索引的  
		// 通过交易ID从账本中得到交易信息
		GetTransactionByID(txID string) (*peer.ProcessedTransaction, error)
	  	// 通过一个区块的哈希值得到该区块
		GetBlockByHash(blockHash []byte) (*common.Block, error)
	  	// 通过交易ID得到包含这个交易的区块
		GetBlockByTxID(txID string) (*common.Block, error)
	  	// 通过交易ID得到该笔交易的理由码。理由码标志着一个交易的状态[1]:有效或无效
		GetTxValidationCodeByTxID(txID string) (peer.TxValidationCode, error)
		// 实例化一个交易模拟器[2]。可以将这个模拟器理解为交易执行的上下文。
		NewTxSimulator() (TxSimulator, error)
	  	// 状态数据库查询器[3]
		NewQueryExecutor() (QueryExecutor, error)
	  	// 历史状态数据库查询器[4]
		NewHistoryQueryExecutor() (HistoryQueryExecutor, error)
	  	// 删除满足某些条件的区块或交易。但目前只是个空方法,并未实现,是一个预留接口。
		Prune(policy commonledger.PrunePolicy) error
	}
  • [1] Fabric中交易的理由码标识的状态有很多种:
    	type TxValidationCode int32
    	const (
    		// 有效
    		TxValidationCode_VALID                        TxValidationCode = 0
    		// 下面都是无效的
    		TxValidationCode_NIL_ENVELOPE                 TxValidationCode = 1
    		TxValidationCode_BAD_PAYLOAD                  TxValidationCode = 2
    		TxValidationCode_BAD_COMMON_HEADER            TxValidationCode = 3
    		TxValidationCode_BAD_CREATOR_SIGNATURE        TxValidationCode = 4
    		TxValidationCode_INVALID_ENDORSER_TRANSACTION TxValidationCode = 5
    		TxValidationCode_INVALID_CONFIG_TRANSACTION   TxValidationCode = 6
    		TxValidationCode_UNSUPPORTED_TX_PAYLOAD       TxValidationCode = 7
    		TxValidationCode_BAD_PROPOSAL_TXID            TxValidationCode = 8
    		TxValidationCode_DUPLICATE_TXID               TxValidationCode = 9
    		TxValidationCode_ENDORSEMENT_POLICY_FAILURE   TxValidationCode = 10
    		TxValidationCode_MVCC_READ_CONFLICT           TxValidationCode = 11
    		TxValidationCode_PHANTOM_READ_CONFLICT        TxValidationCode = 12
    		TxValidationCode_UNKNOWN_TX_TYPE              TxValidationCode = 13
    		TxValidationCode_TARGET_CHAIN_NOT_FOUND       TxValidationCode = 14
    		TxValidationCode_MARSHAL_TX_ERROR             TxValidationCode = 15
    		TxValidationCode_NIL_TXACTION                 TxValidationCode = 16
    		TxValidationCode_EXPIRED_CHAINCODE            TxValidationCode = 17
    		TxValidationCode_CHAINCODE_VERSION_CONFLICT   TxValidationCode = 18
    		TxValidationCode_BAD_HEADER_EXTENSION         TxValidationCode = 19
    		TxValidationCode_BAD_CHANNEL_HEADER           TxValidationCode = 20
    		TxValidationCode_BAD_RESPONSE_PAYLOAD         TxValidationCode = 21
    		TxValidationCode_BAD_RWSET                    TxValidationCode = 22
    		TxValidationCode_ILLEGAL_WRITESET             TxValidationCode = 23
    		// 这个地方可以自行拓展
    		TxValidationCode_INVALID_OTHER_REASON         TxValidationCode = 255
    	)
    
  • [2] Fabric进行交易的第一步就是客户端将交易发给背书节点进行虚拟交易。背书节点在进行模拟交易时就会生成这样一个交易模拟器。交易模拟器中封装了一些对世界状态数据库的操作,比如:GetState()和SetState()等。
    TxSimulator为交易模拟器接口:
    	type TxSimulator interface {
    	  // 继承了账本查询接口(上方已介绍过)
    		QueryExecutor
    		// 设置状态
    		SetState(namespace string, key string, value []byte) error
    		// 删除状态
    		DeleteState(namespace string, key string) error
    	  	// 一次通过多个key来设定多个状态
    		SetStateMultipleKeys(namespace string, kvs map[string][]byte) error
    	  	// 富文本数据状态更新(非KV键值对方式),只针对于CouchDB。
    		ExecuteUpdate(query string) error
    	  	// 获取交易模拟执行的结果。
    	  	// 模拟交易后生成的读写集合,就是通过该方法返回的。
    		GetTxSimulationResults() ([]byte, error)
    	}
    
    智能合约中如果想要增添KV对的话,也是通过该交易模拟器来执行实现的。
  • [3] QueryExecutor为账本查询接口:
    	type QueryExecutor interface {
    		// 根据namespace和键名获取一个状态。namespace由账本ID和链码名组合而成,
    		GetState(namespace string, key string) ([]byte, error)
    		// 一次调用中根据多个键值获取多个状态
    		GetStateMultipleKeys(namespace string, keys []string) ([][]byte, error).
    		// 获取状态区间。区间范围从startKey到endKey,返回一个结果迭代器。可以从迭代器中取出结果。
    		GetStateRangeScanIterator(namespace string, startKey string, endKey string) (commonledger.ResultsIterator, error)
    	//以上三个查询都是针对KV键值对的查询
    	  
    	  	// 模糊查询(富文本格式查询),非KV键值对查询。只适用于CouchDB
    		ExecuteQuery(namespace, query string) (commonledger.ResultsIterator, error)
    		// 释放该账本接口对象占用的资源
    		Done()
    	}
    
  • [4] HistoryQueryExecutor为历史状态查询接口
    	type HistoryQueryExecutor interface {
    		// 根据给出的key从历史状态数据库中获取该key的所有状态变动历史
    		// namespace通过账本ID和链码名来定位。
    		GetHistoryForKey(namespace string, key string) (commonledger.ResultsIterator, error)
    	}
    

3 ValidatedLedger接口-账本存储

ValidatedLedger接口用来指代账本存储,做一层封装

	type ValidatedLedger interface {
	  // 账本的文件存储对象
		commonledger.Ledger 
	}

ps:
本人热爱图灵,热爱中本聪,热爱V神,热爱一切被梨花照过的姑娘。
以下是我个人的公众号,如果有技术问题可以关注我的公众号来跟我交流。
同时我也会在这个公众号上每周更新我的原创文章,喜欢的小伙伴或者老伙计可以支持一下!
如果需要转发,麻烦注明作者。十分感谢!
Michael.W谈hyperledger Fabric第24期-详细带读Fabric的源码9-peer节点有关账本的重要接口
公众号名称:后现代泼痞浪漫主义奠基人