区块链教程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

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

相关文章
|
1月前
|
存储 供应链 监控
区块链技术在供应链管理中的应用与前景分析
随着信息化时代的到来,供应链管理面临着越来越多的挑战和机遇。本文主要探讨了区块链技术在供应链管理中的应用,以及未来的发展前景。通过对区块链技术的特点和优势进行分析,结合实际案例和趋势展望,展示了区块链技术在提升供应链透明度、效率和安全性方面的潜力,以及未来发展的可能方向。
|
1月前
|
存储 供应链 安全
【区块链】智能交易模式下的数据安全流通模型
【区块链】智能交易模式下的数据安全流通模型
225 1
|
1月前
|
安全 数据挖掘 API
《区块链公链数据分析简易速速上手小册》第4章:交易数据分析(2024 最新版)(下)
《区块链公链数据分析简易速速上手小册》第4章:交易数据分析(2024 最新版)(下)
61 1
|
1月前
|
数据可视化 数据挖掘 区块链
《区块链公链数据分析简易速速上手小册》第4章:交易数据分析(2024 最新版)(上)
《区块链公链数据分析简易速速上手小册》第4章:交易数据分析(2024 最新版)(上)
72 0
|
21天前
|
存储 供应链 安全
基于区块链技术的智能合约安全性分析
【5月更文挑战第31天】本文深入探讨了区块链技术中智能合约的安全性问题,通过分析现有智能合约的安全漏洞和攻击手段,提出了一系列增强智能合约安全性的策略。文章首先介绍了区块链和智能合约的基本概念,随后详细讨论了智能合约面临的安全挑战,包括代码漏洞、重入攻击等问题,并对比分析了不同平台下智能合约的安全性差异。最后,文章提出了一系列提高智能合约安全性的建议,旨在为区块链应用的健康发展提供参考。
|
1天前
|
区块链
近期区块链市场趋势分析
**区块链市场趋势摘要:** - 跨链技术成熟,提升互操作性,助力区块链网络融合。 - DeFi持续繁荣,智能合约与AMM创新活跃,市场竞争驱动市场壮大。 - NFT市场多样化,拓展至游戏、音乐等领域,实用性增强。 - 区块链寻求绿色转型,通过PoS共识与绿色能源减少能耗。 - 技术模块化、可组合性提升,降低成本,增强系统灵活性。 这些趋势展现区块链潜力,带来机遇与挑战,促进行业创新。
|
27天前
|
存储 算法 安全
区块链系统开发技术规则分析
区块链核心技术包括:1) 哈希算法,利用单向函数将任意数据转化为固定长度代码,确保安全验证;2) 非对称加密,使用公钥和私钥一对进行加密解密,保证信息安全;3) 共识机制,如PoW、PoS、DPoS等,实现快速交易验证和确认;4) 智能合约,自动执行的可信代码,一旦编写即不可更改,用于自动化交易;5) 分布式存储,将数据分散存储在网络各处,涵盖结构化、非结构化和半结构化数据。
|
1月前
|
供应链 区块链 数据安全/隐私保护
探索区块链技术在金融领域的应用与前景分析
本文将深入探讨区块链技术在金融领域的具体应用场景,分析其优势与挑战,并展望未来发展趋势。通过案例分析和技术解析,揭示区块链技术在金融行业中的革新意义及前景。
221 15
|
9月前
|
区块链
区块链的发币流程技术分析
区块链现在是发展的如火如荼,很多人都想趁着这个风口,投入区块链创业的浪潮中。 那么我们该怎么做才能抓住这个机会呢? 进行区块链发币要求是很多的,主要有以下几个步骤。
|
9月前
|
安全 算法 区块链
区块链交易所开发技术说明:智能合约设计与实现步骤实现分析
智能合约是区块链技术的核心应用,其能够自动执行、验证和执行合同,并以可验证的方式进行操作。在区块链交易所中,智能合约扮演着重要的角色,它们保证了交易的透明性、效率和安全性。作为一名专业的交易所开发团队一员,在交易所开发这块拥有相对成熟的开发技术,目前已经有成熟的区块链交易所开发案例。本文将介绍如何设计和实现可靠的智能合约来支持区块链交易所。

热门文章

最新文章