1. 程式人生 > >hyperledger fabric 1.0 原始碼分析之peer chaincode upgrade

hyperledger fabric 1.0 原始碼分析之peer chaincode upgrade

描述

peer chaincode upgrade命令用於對chaincode升級。

定義

func upgradeCmd(cf *ChaincodeCmdFactory) *cobra.Command {
	chaincodeUpgradeCmd = &cobra.Command{
		Use:       upgradeCmdName,
		Short:     "Upgrade chaincode.",
		Long:      "Upgrade an existing chaincode with the specified one. The new chaincode will immediately replace the existing chaincode upon the transaction committed.",
		ValidArgs: []string{"1"},
		RunE: func(cmd *cobra.Command, args []string) error {
            //命令執行入口
			return chaincodeUpgrade(cmd, args, cf)
		},
	}
    //新增命令標記
	flagList := []string{
		"lang",
		"ctor",
		"path",
		"name",
		"channelID",
		"version",
		"policy",
		"escc",
		"vscc",
	}
	attachFlags(chaincodeUpgradeCmd, flagList)

	return chaincodeUpgradeCmd
}

入口函式

func chaincodeUpgrade(cmd *cobra.Command, args []string, cf *ChaincodeCmdFactory) error {
	var err error
	if cf == nil {
        //初始化ChaincodeCmdFactory
		cf, err = InitCmdFactory(true, true)
		if err != nil {
			return err
		}
	}
	defer cf.BroadcastClient.Close()
    //升級過程
	env, err := upgrade(cmd, cf)
	if err != nil {
		return err
	}

	if env != nil {
		logger.Debug("Send signed envelope to orderer")
        //傳送簽名信封到orderer進行廣播
		err = cf.BroadcastClient.Send(env)
		return err
	}

	return nil
}

升級過程

func upgrade(cmd *cobra.Command, cf *ChaincodeCmdFactory) (*protcommon.Envelope, error) {
	//獲取到ChaincodeSpec
    spec, err := getChaincodeSpec(cmd)
	if err != nil {
		return nil, err
	}
    //獲取到ChaincodeDeploymentSpec
	cds, err := getChaincodeDeploymentSpec(spec, false)
	if err != nil {
		return nil, fmt.Errorf("Error getting chaincode code %s: %s", chainFuncName, err)
	}
    //獲取msp所有者身份
	creator, err := cf.Signer.Serialize()
	if err != nil {
		return nil, fmt.Errorf("Error serializing identity for %s: %s", cf.Signer.GetIdentifier(), err)
	}
    //從ChaincodeDeploymentSpec建立chinacode升級的提案
	prop, _, err := utils.CreateUpgradeProposalFromCDS(chainID, cds, creator, policyMarhsalled, []byte(escc), []byte(vscc))
	if err != nil {
		return nil, fmt.Errorf("Error creating proposal %s: %s", chainFuncName, err)
	}
	logger.Debugf("Get upgrade proposal for chaincode <%v>", spec.ChaincodeId)
    
	var signedProp *pb.SignedProposal
    //對提案進行簽名
	signedProp, err = utils.GetSignedProposal(prop, cf.Signer)
	if err != nil {
		return nil, fmt.Errorf("Error creating signed proposal  %s: %s", chainFuncName, err)
	}
    //將提案發送至背書端,返回模擬簽名後的響應資料
	proposalResponse, err := cf.EndorserClient.ProcessProposal(context.Background(), signedProp)
	if err != nil {
		return nil, fmt.Errorf("Error endorsing %s: %s", chainFuncName, err)
	}
	logger.Debugf("endorse upgrade proposal, get response <%v>", proposalResponse.Response)

	if proposalResponse != nil {
		// assemble a signed transaction (it's an Envelope message)
        //背書端模擬成功後,建立簽名交易資訊,最終返回簽名信封env
		env, err := utils.CreateSignedTx(prop, cf.Signer, proposalResponse)
		if err != nil {
			return nil, fmt.Errorf("Could not assemble transaction, err %s", err)
		}
		logger.Debug("Get Signed envelope")
		return env, nil
	}

	return nil, nil
}

這裡的方法之前都有詳細註釋,這裡就不在寫了