区块链教程Fabric1.0源代码分析配置交易-生成通道配置二

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了区块链教程Fabric1.0源代码分析配置交易-生成通道配置二相关的知识,希望对你有一定的参考价值。

区块链教程Fabric1.0源代码分析配置交易-生成通道配置二。Generator接口实现,即bootstrapper。

type bootstrapper struct {
????channelGroups     []*cb.ConfigGroup
????ordererGroups     []*cb.ConfigGroup
????applicationGroups []*cb.ConfigGroup
????consortiumsGroups []*cb.ConfigGroup
}

func New(conf *genesisconfig.Profile) Generator
func (bs *bootstrapper) ChannelTemplate() configtx.Template
func (bs *bootstrapper) GenesisBlock() *cb.Block
func (bs *bootstrapper) GenesisBlockForChannel(channelID string) *cb.Block
//代码在common/configtx/tool/provisional/provisional.go

func New(conf *genesisconfig.Profile) Generator代码如下:

func New(conf *genesisconfig.Profile) Generator {
????bs := &bootstrapper{
????????channelGroups: []*cb.ConfigGroup{
????????????config.DefaultHashingAlgorithm(), //默认哈希函数
????????????config.DefaultBlockDataHashingStructure(), //默认块数据哈希结构
????????????
????????????//默认通道策略,包括读策略、写策略和管理策略
????????????//ReadersPolicyKey = "Readers",ImplicitMetaPolicy_ANY,任意
????????????policies.TemplateImplicitMetaAnyPolicy([]string{}, configvaluesmsp.ReadersPolicyKey),
????????????//WritersPolicyKey = "Writers",ImplicitMetaPolicy_ANY,任意
????????????policies.TemplateImplicitMetaAnyPolicy([]string{}, configvaluesmsp.WritersPolicyKey),
????????????//AdminsPolicyKey = "Admins",ImplicitMetaPolicy_MAJORITY,大多数
????????????policies.TemplateImplicitMetaMajorityPolicy([]string{}, configvaluesmsp.AdminsPolicyKey),
????????},
????}

????if conf.Orderer != nil { //系统通道配置
????????oa := config.TemplateOrdererAddresses(conf.Orderer.Addresses) //设置Orderer地址
????????oa.Values[config.OrdererAddressesKey].ModPolicy = OrdererAdminsPolicy //OrdererAdminsPolicy = "/Channel/Orderer/Admins"

????????bs.ordererGroups = []*cb.ConfigGroup{
????????????oa,
????????????config.TemplateConsensusType(conf.Orderer.OrdererType), //设置共识插件类型
????????????config.TemplateBatchSize(&ab.BatchSize{ //设置批处理大小
????????????????MaxMessageCount:   conf.Orderer.BatchSize.MaxMessageCount,
????????????????AbsoluteMaxBytes:  conf.Orderer.BatchSize.AbsoluteMaxBytes,
????????????????PreferredMaxBytes: conf.Orderer.BatchSize.PreferredMaxBytes,
????????????}),
????????????config.TemplateBatchTimeout(conf.Orderer.BatchTimeout.String()), //设置批处理超时
????????????config.TemplateChannelRestrictions(conf.Orderer.MaxChannels), //设置最大通道数

????????????//初始化Orderer读、写、管理策略
????????????policies.TemplateImplicitMetaPolicyWithSubPolicy([]string{config.OrdererGroupKey}, BlockValidationPolicyKey, configvaluesmsp.WritersPolicyKey, cb.ImplicitMetaPolicy_ANY),
????????????policies.TemplateImplicitMetaAnyPolicy([]string{config.OrdererGroupKey}, configvaluesmsp.ReadersPolicyKey),
????????????policies.TemplateImplicitMetaAnyPolicy([]string{config.OrdererGroupKey}, configvaluesmsp.WritersPolicyKey),
????????????policies.TemplateImplicitMetaMajorityPolicy([]string{config.OrdererGroupKey}, configvaluesmsp.AdminsPolicyKey),
????????}

????????for _, org := range conf.Orderer.Organizations {
????????????mspConfig, err := msp.GetVerifyingMspConfig(org.MSPDir, org.ID)
????????????bs.ordererGroups = append(bs.ordererGroups,
????????????????configvaluesmsp.TemplateGroupMSPWithAdminRolePrincipal([]string{config.OrdererGroupKey, org.Name},
????????????????????mspConfig, org.AdminPrincipal == genesisconfig.AdminRoleAdminPrincipal,
????????????????),
????????????)
????????}

????????switch conf.Orderer.OrdererType {
????????case ConsensusTypeSolo:
????????case ConsensusTypeKafka:
????????????bs.ordererGroups = append(bs.ordererGroups, config.TemplateKafkaBrokers(conf.Orderer.Kafka.Brokers)) //设置Kafka
????????default:
????????}
????}

????if conf.Application != nil { //应用通道配置
????????bs.applicationGroups = []*cb.ConfigGroup{
????????????policies.TemplateImplicitMetaAnyPolicy([]string{config.ApplicationGroupKey}, configvaluesmsp.ReadersPolicyKey),
????????????policies.TemplateImplicitMetaAnyPolicy([]string{config.ApplicationGroupKey}, configvaluesmsp.WritersPolicyKey),
????????????policies.TemplateImplicitMetaMajorityPolicy([]string{config.ApplicationGroupKey}, configvaluesmsp.AdminsPolicyKey),
????????}
????????for _, org := range conf.Application.Organizations {
????????????mspConfig, err := msp.GetVerifyingMspConfig(org.MSPDir, org.ID)
????????????bs.applicationGroups = append(bs.applicationGroups,
????????????????configvaluesmsp.TemplateGroupMSPWithAdminRolePrincipal([]string{config.ApplicationGroupKey, org.Name},
????????????????????mspConfig, org.AdminPrincipal == genesisconfig.AdminRoleAdminPrincipal,
????????????????),
????????????)
????????????var anchorProtos []*pb.AnchorPeer
????????????for _, anchorPeer := range org.AnchorPeers {
????????????????anchorProtos = append(anchorProtos, &pb.AnchorPeer{
????????????????????Host: anchorPeer.Host,
????????????????????Port: int32(anchorPeer.Port),
????????????????})
????????????}
????????????bs.applicationGroups = append(bs.applicationGroups, config.TemplateAnchorPeers(org.Name, anchorProtos))
????????}

????}

????if conf.Consortiums != nil { //联盟相关
????????tcg := config.TemplateConsortiumsGroup()
????????tcg.Groups[config.ConsortiumsGroupKey].ModPolicy = OrdererAdminsPolicy
????????tcg.Groups[config.ConsortiumsGroupKey].Policies[configvaluesmsp.AdminsPolicyKey] = &cb.ConfigPolicy{
????????????Policy: &cb.Policy{
????????????????Type:  int32(cb.Policy_SIGNATURE),
????????????????Value: utils.MarshalOrPanic(cauthdsl.AcceptAllPolicy),
????????????},
????????????ModPolicy: OrdererAdminsPolicy,
????????}
????????bs.consortiumsGroups = append(bs.consortiumsGroups, tcg)
????????for consortiumName, consortium := range conf.Consortiums {
????????????cg := config.TemplateConsortiumChannelCreationPolicy(consortiumName, policies.ImplicitMetaPolicyWithSubPolicy(
????????????????configvaluesmsp.AdminsPolicyKey,
????????????????cb.ImplicitMetaPolicy_ANY,
????????????).Policy)

????????????cg.Groups[config.ConsortiumsGroupKey].Groups[consortiumName].ModPolicy = OrdererAdminsPolicy
????????????cg.Groups[config.ConsortiumsGroupKey].Groups[consortiumName].Values[config.ChannelCreationPolicyKey].ModPolicy = OrdererAdminsPolicy
????????????bs.consortiumsGroups = append(bs.consortiumsGroups, cg)

????????????for _, org := range consortium.Organizations {
????????????????mspConfig, err := msp.GetVerifyingMspConfig(org.MSPDir, org.ID)
????????????????bs.consortiumsGroups = append(bs.consortiumsGroups,
????????????????????configvaluesmsp.TemplateGroupMSPWithAdminRolePrincipal(
????????????????????????[]string{config.ConsortiumsGroupKey, consortiumName, org.Name},
????????????????????????mspConfig, org.AdminPrincipal == genesisconfig.AdminRoleAdminPrincipal,
????????????????????),
????????????????)
????????????}
????????}
????}

????return bs
}
//代码在common/configtx/tool/provisional/provisional.go

func (bs bootstrapper) GenesisBlockForChannel(channelID string) cb.Block代码如下:

func (bs *bootstrapper) GenesisBlockForChannel(channelID string) *cb.Block {
????block, err := genesis.NewFactoryImpl(
????????configtx.NewModPolicySettingTemplate(
????????????configvaluesmsp.AdminsPolicyKey,
????????????configtx.NewCompositeTemplate(
????????????????configtx.NewSimpleTemplate(bs.consortiumsGroups...),
????????????????bs.ChannelTemplate(),
????????????),
????????),
????).Block(channelID)
????return block
}

//代码在common/configtx/tool/provisional/provisional.go

5、configtxgen命令

5.1、main函数

func main() {
????var outputBlock, outputChannelCreateTx, profile, channelID, inspectBlock, inspectChannelCreateTx, outputAnchorPeersUpdate, asOrg string

????//-outputBlock,初始区块写入指定文件
????flag.StringVar(&outputBlock, "outputBlock", "", "The path to write the genesis block to (if set)")
????//-channelID,指定通道名称
????flag.StringVar(&channelID, "channelID", provisional.TestChainID, "The channel ID to use in the configtx")
????//-outputCreateChannelTx,将通道创建交易写入指定文件
????flag.StringVar(&outputChannelCreateTx, "outputCreateChannelTx", "", "The path to write a channel creation configtx to (if set)")
????//-profile,指定profile
????flag.StringVar(&profile, "profile", genesisconfig.SampleInsecureProfile, "The profile from configtx.yaml to use for generation.")
????//-inspectBlock,打印指定区块的配置信息
????flag.StringVar(&inspectBlock, "inspectBlock", "", "Prints the configuration contained in the block at the specified path")
????//-inspectChannelCreateTx,打印通道创建交易文件中的配置更新信息
????flag.StringVar(&inspectChannelCreateTx, "inspectChannelCreateTx", "", "Prints the configuration contained in the transaction at the specified path")
????//-outputAnchorPeersUpdate,生成锚节点配置更新文件,需同时指定-asOrg
????flag.StringVar(&outputAnchorPeersUpdate, "outputAnchorPeersUpdate", "", "Creates an config update to update an anchor peer (works only with the default channel creation, and only for the first update)")
????//-asOrg,以指定身份执行更新配置交易,如更新锚节点配置信息
????flag.StringVar(&asOrg, "asOrg", "", "Performs the config generation as a particular organization (by name), only including values in the write set that org (likely) has privilege to set")
????flag.Parse()

????factory.InitFactories(nil)
????config := genesisconfig.Load(profile) //读取指定配置

????if outputBlock != "" { //生成Orderer服务启动的初始区块
????????err := doOutputBlock(config, channelID, outputBlock)
????}
????if outputChannelCreateTx != "" { //生成新建应用通道的配置交易
????????err := doOutputChannelCreateTx(config, channelID, outputChannelCreateTx)
????}
????if outputAnchorPeersUpdate != "" { //生成锚节点配置更新文件
????????err := doOutputAnchorPeersUpdate(config, channelID, outputAnchorPeersUpdate, asOrg)
????}
}
//代码在common/configtx/tool/configtxgen/main.go

5.2、doOutputBlock(生成Orderer服务启动的初始区块,即系统通道的初始区块文件)

func doOutputBlock(config *genesisconfig.Profile, channelID string, outputBlock string) error {
????pgen := provisional.New(config) //构建Generator实例
????genesisBlock := pgen.GenesisBlockForChannel(channelID) //生成创世区块
????err := ioutil.WriteFile(outputBlock, utils.MarshalOrPanic(genesisBlock), 0644) //创世区块写入文件
????return nil
}
//代码在common/configtx/tool/configtxgen/main.go

genesis更详细内容,参考:Fabric 1.0源代码笔记 之 configtx(配置交易) #genesis(系统通道创世区块)

5.3、doOutputChannelCreateTx(生成新建应用通道的配置交易)

func doOutputChannelCreateTx(conf *genesisconfig.Profile, channelID string, outputChannelCreateTx string) error {
????var orgNames []string
????for _, org := range conf.Application.Organizations {
????????orgNames = append(orgNames, org.Name)
????}
????configtx, err := configtx.MakeChainCreationTransaction(channelID, conf.Consortium, nil, orgNames...)
????err = ioutil.WriteFile(outputChannelCreateTx, utils.MarshalOrPanic(configtx), 0644)
????return nil
}
//代码在common/configtx/tool/configtxgen/main.go

5.4、doOutputAnchorPeersUpdate(生成锚节点配置更新文件)

func doOutputAnchorPeersUpdate(conf *genesisconfig.Profile, channelID string, outputAnchorPeersUpdate string, asOrg string) error {
????var org *genesisconfig.Organization
????for _, iorg := range conf.Application.Organizations {
????????if iorg.Name == asOrg {
????????????org = iorg
????????}
????}
????anchorPeers := make([]*pb.AnchorPeer, len(org.AnchorPeers))
????for i, anchorPeer := range org.AnchorPeers {
????????anchorPeers[i] = &pb.AnchorPeer{
????????????Host: anchorPeer.Host,
????????????Port: int32(anchorPeer.Port),
????????}
????}

????configGroup := config.TemplateAnchorPeers(org.Name, anchorPeers)
????configGroup.Groups[config.ApplicationGroupKey].Groups[org.Name].Values[config.AnchorPeersKey].ModPolicy = mspconfig.AdminsPolicyKey
????configUpdate := &cb.ConfigUpdate{
????????ChannelId: channelID,
????????WriteSet:  configGroup,
????????ReadSet:   cb.NewConfigGroup(),
????}

????configUpdate.ReadSet.Groups[config.ApplicationGroupKey] = cb.NewConfigGroup()
????configUpdate.ReadSet.Groups[config.ApplicationGroupKey].Version = 1
????configUpdate.ReadSet.Groups[config.ApplicationGroupKey].ModPolicy = mspconfig.AdminsPolicyKey
????configUpdate.ReadSet.Groups[config.ApplicationGroupKey].Groups[org.Name] = cb.NewConfigGroup()
????configUpdate.ReadSet.Groups[config.ApplicationGroupKey].Groups[org.Name].Values[config.MSPKey] = &cb.ConfigValue{}
????configUpdate.ReadSet.Groups[config.ApplicationGroupKey].Groups[org.Name].Policies[mspconfig.ReadersPolicyKey] = &cb.ConfigPolicy{}
????configUpdate.ReadSet.Groups[config.ApplicationGroupKey].Groups[org.Name].Policies[mspconfig.WritersPolicyKey] = &cb.ConfigPolicy{}
????configUpdate.ReadSet.Groups[config.ApplicationGroupKey].Groups[org.Name].Policies[mspconfig.AdminsPolicyKey] = &cb.ConfigPolicy{}

????configUpdate.WriteSet.Groups[config.ApplicationGroupKey].Version = 1
????configUpdate.WriteSet.Groups[config.ApplicationGroupKey].ModPolicy = mspconfig.AdminsPolicyKey
????configUpdate.WriteSet.Groups[config.ApplicationGroupKey].Groups[org.Name].Version = 1
????configUpdate.WriteSet.Groups[config.ApplicationGroupKey].Groups[org.Name].ModPolicy = mspconfig.AdminsPolicyKey
????configUpdate.WriteSet.Groups[config.ApplicationGroupKey].Groups[org.Name].Values[config.MSPKey] = &cb.ConfigValue{}
????configUpdate.WriteSet.Groups[config.ApplicationGroupKey].Groups[org.Name].Policies[mspconfig.ReadersPolicyKey] = &cb.ConfigPolicy{}
????configUpdate.WriteSet.Groups[config.ApplicationGroupKey].Groups[org.Name].Policies[mspconfig.WritersPolicyKey] = &cb.ConfigPolicy{}
????configUpdate.WriteSet.Groups[config.ApplicationGroupKey].Groups[org.Name].Policies[mspconfig.AdminsPolicyKey] = &cb.ConfigPolicy{}

????configUpdateEnvelope := &cb.ConfigUpdateEnvelope{
????????ConfigUpdate: utils.MarshalOrPanic(configUpdate),
????}

????update := &cb.Envelope{
????????Payload: utils.MarshalOrPanic(&cb.Payload{
????????????Header: &cb.Header{
????????????????ChannelHeader: utils.MarshalOrPanic(&cb.ChannelHeader{
????????????????????ChannelId: channelID,
????????????????????Type:      int32(cb.HeaderType_CONFIG_UPDATE),
????????????????}),
????????????},
????????????Data: utils.MarshalOrPanic(configUpdateEnvelope),
????????}),
????}

????err := ioutil.WriteFile(outputAnchorPeersUpdate, utils.MarshalOrPanic(update), 0644)
????return nil
}

//代码在common/configtx/tool/configtxgen/main.go

欢迎继续关注兄弟连区块链教程分享!

以上是关于区块链教程Fabric1.0源代码分析配置交易-生成通道配置二的主要内容,如果未能解决你的问题,请参考以下文章

兄弟连区块链教程Fabric1.0源代码分析ledgerID数据

区块链教程Fabric1.0源代码分析Peer peer根命令入口及加载子命令二

区块链教程Fabric1.0源代码分析MSP成员关系服务提供者二

区块链教程Fabric1.0源代码分析Ledger historydb历史数据库

fabric1.0学习笔记

比特币创建交易源码分析