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中账本是按照通道进行隔离的,也就是说一个通道就会有一个账本。
并且一个账本中会对应三种数据:
- 账本数据
- 状态数据
- 历史数据
通过账本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为交易模拟器接口:
智能合约中如果想要增添KV对的话,也是通过该交易模拟器来执行实现的。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) }
- [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神,热爱一切被梨花照过的姑娘。
以下是我个人的公众号,如果有技术问题可以关注我的公众号来跟我交流。
同时我也会在这个公众号上每周更新我的原创文章,喜欢的小伙伴或者老伙计可以支持一下!
如果需要转发,麻烦注明作者。十分感谢!
公众号名称:后现代泼痞浪漫主义奠基人