超级账本源码解析之MSP

本系列目录:超级账本源码(V1.3)解析目录

Cryptogen

为了更好的理解Fabric中MSP是如何工作的,我们先通过源码来看一下Fabric提供的Cryptogen这个命令行工具到底做了什么。

核心代码在common/tools/cryptogen这个目录下,目录树如下:

cryptogen
├── ca
│   ├── ca_test.go
│   └── generator.go
├── csp
│   ├── csp.go
│   └── csp_test.go
├── main.go
├── metadata
│   ├── metadata.go
│   └── metadata_test.go
└── msp
    ├── generator.go
    ├── msp_internal_test.go
    └── msp_test.go

该命令需要指定一个配置文件作为输入,我们使用了first-network中默认的配置文件crypto-config.yaml,运行该命令后,生成了crypto-config目录,里面包含了生成的相关证书和秘钥等文件。

crypto-config.yaml文件如下:

# ---------------------------------------------------------------------------
# "OrdererOrgs" - Definition of organizations managing orderer nodes
# ---------------------------------------------------------------------------
OrdererOrgs:
  - Name: Orderer
    Domain: example.com
    Specs:
      - Hostname: orderer

# ---------------------------------------------------------------------------
# "PeerOrgs" - Definition of organizations managing peer nodes
# ---------------------------------------------------------------------------
PeerOrgs:
  - Name: Org1
    Domain: org1.example.com
    EnableNodeOUs: true
    Template:
      Count: 2  # peer数量
    Users:
      Count: 1  # user数量
      
  - Name: Org2
    Domain: org2.example.com
    EnableNodeOUs: true
    Template:
      Count: 2
    Users:
      Count: 1

执行cryptogen generate --config=crypto-config.yaml后,对每一个Org(Orderer、Org1 、Org2)依次生成了

  1. 签名CA的私钥和自签名证书
  2. TLS CA的私钥和自签名证书
  3. 该Org的msp,其中包含签名CA和TLS CA的证书(cacerts和tlscacerts),以及一个管理员证书(admincerts,临时的),如果支持nodeOU还会成成一个config.yaml
  4. 生成该Org的peer的证书相关的材料:包含一对公私钥(以及签名CA签名的证书)和另一对公私钥(以及tls CA签名的证书),同时将两个CA的证书复制到该peer的msp目录下,将签名公钥对应的证书作为临时的管理员证书(admincerts)
  5. 生成该Org的user的证书相关的材料:除了crypto-config.yamlCount指定的user数量外,还生成了一个管理员用户admin,都是两对公私钥以及对应CA为其签名的证书,将签名CA颁发的证书同时作为该user的管理员证书,同时将admin用户的管理员证书复制到该Org的msp以及peer的msp下的管理员证书目录(替换掉临时的证书)

总之,每个组织都有自己的CA(一个签名CA、一个TLS CA),该组织的成员(peer或者user)下的msp目录都含有这两个CA的证书和该成员自身的公私钥及证书(由签名CA颁发),每个组织默认生成一个管理员用户(admin),该admin的证书被复制到该组织的msp目录以及各peer的msp目录下。

MSP初始化

在peer启动时,调用了peer/common/common.go中的InitCmd函数,然后调用了InitCrypto函数,其中设置了该peer的加密参数,并调用了msp/mgmt/mgmt.go中的LoadLocalMspWithType函数初始化该peer的msp。

LoadLocalMspWithType函数读取了该peer对应的msp目录下的相关文件生成了msp config,并最终调用了msp/mspimpl.go下的Setup根据该config初始化了MSP。

func (msp *bccspmsp) preSetupV1(conf *m.FabricMSPConfig) error {
    
    
	// setup crypto config
	if err := msp.setupCrypto(conf); err != nil {
    
    
		return err
	}

	// Setup CAs
	if err := msp.setupCAs(conf); err != nil {
    
    
		return err
	}

	// Setup Admins
	if err := msp.setupAdmins(conf); err != nil {
    
    
		return err
	}

	// Setup CRLs
	if err := msp.setupCRLs(conf); err != nil {
    
    
		return err
	}

	// Finalize setup of the CAs
	if err := msp.finalizeSetupCAs(conf); err != nil {
    
    
		return err
	}

	// setup the signer (if present)
	if err := msp.setupSigningIdentity(conf); err != nil {
    
    
		return err
	}

	// setup TLS CAs
	if err := msp.setupTLSCAs(conf); err != nil {
    
    
		return err
	}

	// setup the OUs
	if err := msp.setupOUs(conf); err != nil {
    
    
		return err
	}

	return nil
}

MSP如何参与到Fabric中的各方面

接下来我们通过解析一个交易的完整生命周期来说明MSP的作用。

发起一个交易,从peer/chaincode/invoke.gochaincodeInvoke函数开始;

  1. InitCmdFactory中通过signer, err := common.GetDefaultSignerFnc()获取了该peer的私钥(signer)用来后续签名使用。
  2. peer/chaincode/common.gopeer/chaincode/common.go函数中完成交易流程
    1. 创建了proposal(包含了creator,也就是签名者(的公钥和mspid)),调用signedProp, err := putils.GetSignedProposal(prop, signer)对proposal签名
    2. 通过grpc调用了core/endorser/endorser.go中的ProcessProposal来为该交易背书,其中在preProcess函数中,调用了core/common/validation/msgvalidation.go中的ValidateProposalMessage函数
    3. ValidateProposalMessage函数中,err = checkSignatureFromCreator(shdr.Creator, signedProp.Signature, signedProp.ProposalBytes, chdr.ChannelId) 检查了该proposal的签名的有效性
    4. core/endorser/endorser.go中的endorseProposal函数最终调用core/handlers/endorsement/builtin/default_endorsement.go中的Endorse创建了endorsement,使用该peer的私钥为该交易签名背书
    5. 当client收集到足够的endorsement后,使用env, err := putils.CreateSignedTx(prop, signer, responses...)创建了该交易的envelop(包含了endorsement)并为其签名,发给orderer。
    6. orderer将envelop打包成block,最终发给fabric网络中的其他peer。
    7. 其他peer启动【VSCC】【MVCC】【Commit】过程,交易结束。其中在VSCC过程中验证了该tx的envelop签名,并检查该envelop中携带的的endorsements是否满足该chaincode的endorsement policy(TODO)。

猜你喜欢

转载自blog.csdn.net/yijiull/article/details/108566921