peer/chaincode/chaincode.go
peer/chaincode/install.go
peer/chaincode/common.go
chaincode.go
func Cmd(cf *ChaincodeCmdFactory) *cobra.Command {
addFlags(chaincodeCmd)
chaincodeCmd.AddCommand(installCmd(cf)) // 添加install
chaincodeCmd.AddCommand(instantiateCmd(cf)) // 添加instantiate
chaincodeCmd.AddCommand(invokeCmd(cf)) // 添加invoke
chaincodeCmd.AddCommand(packageCmd(cf, nil)) // 添加package
chaincodeCmd.AddCommand(queryCmd(cf)) // 添加query
chaincodeCmd.AddCommand(signpackageCmd(cf)) // 添加signpackage
chaincodeCmd.AddCommand(upgradeCmd(cf)) // 添加更新
chaincodeCmd.AddCommand(listCmd(cf)) // 添加list
return chaincodeCmd
}
var chaincodeCmd = &cobra.Command{
Use: chainFuncName,
Short: fmt.Sprint(shortDes),
Long: fmt.Sprint(longDes),
//prerun设置order环境
PersistentPreRun: common.SetOrdererEnv,
}
install.go
// 安装链码命令
func installCmd(cf *ChaincodeCmdFactory) *cobra.Command {
chaincodeInstallCmd = &cobra.Command{
Use: "install",
Short: fmt.Sprint(installDesc),
Long: fmt.Sprint(installDesc),
ValidArgs: []string{"1"},
RunE: func(cmd *cobra.Command, args []string) error {
var ccpackfile string
if len(args) > 0 {
ccpackfile = args[0]
}
//安装
return chaincodeInstall(cmd, ccpackfile, cf)
},
}
flagList := []string{
"lang",
"ctor",
"path",
"name",
"version",
}
attachFlags(chaincodeInstallCmd, flagList)
return chaincodeInstallCmd
}
//安装到peer,通过背书客户端的ProcessProposal,背书服务调用LSCC的invoke
func install(msg proto.Message, cf *ChaincodeCmdFactory) error {
creator, err := cf.Signer.Serialize()
if err != nil {
return fmt.Errorf("Error serializing identity for %s: %s", cf.Signer.GetIdentifier(), err)
}
//创建提案消息
prop, _, err := utils.CreateInstallProposalFromCDS(msg, creator)
if err != nil {
return fmt.Errorf("Error creating proposal %s: %s", chainFuncName, err)
}
//签名消息
var signedProp *pb.SignedProposal
signedProp, err = utils.GetSignedProposal(prop, cf.Signer)
if err != nil {
return fmt.Errorf("Error creating signed proposal %s: %s", chainFuncName, err)
}
//背书节点处理消息
proposalResponse, err := cf.EndorserClient.ProcessProposal(context.Background(), signedProp)
//处理结果
if err != nil {
return fmt.Errorf("Error endorsing %s: %s", chainFuncName, err)
}
if proposalResponse != nil {
logger.Debugf("Installed remotely %v", proposalResponse)
}
return nil
}
fabric/protos/utils/proputils.go
func CreateInstallProposalFromCDS(ccpack proto.Message, creator []byte) (*peer.Proposal, string, error) {
// prop类型install
return createProposalFromCDS("", ccpack, creator, "install")
}
//创建提案消息
func createProposalFromCDS(chainID string, msg proto.Message, creator []byte, propType string, args ...[]byte) (*peer.Proposal, string, error) {
。。。
switch propType {
case "deploy":
// 和upgrade是一样的流程
fallthrough
case "upgrade":
。。。
}
//系统链码描述.
lsccSpec := &peer.ChaincodeInvocationSpec{
ChaincodeSpec: &peer.ChaincodeSpec{
Type: peer.ChaincodeSpec_GOLANG,
//调用lscc系统链码
ChaincodeId: &peer.ChaincodeID{Name: "lscc"},
Input: ccinp}}
//...and get the proposal for it
//HeaderType_ENDORSER_TRANSACTION消息类型
return CreateProposalFromCIS(common.HeaderType_ENDORSER_TRANSACTION, chainID, lsccSpec, creator)
}
fabric/protos/peer/peeer.pb.go
func (c *endorserClient) ProcessProposal(ctx context.Context, in *SignedProposal, opts ...grpc.CallOption) (*ProposalResponse, error) {
out := new(ProposalResponse)
err := grpc.Invoke(ctx, "/protos.Endorser/ProcessProposal", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
return out, nil
}
fabric/core/scc/lscc.go
调用invoke方法
func (lscc *lifeCycleSysCC) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
args := stub.GetArgs()
if len(args) < 1 {
return shim.Error(InvalidArgsLenErr(len(args)).Error())
}
function := string(args[0])
// 1.获取签名的消息
sp, err := stub.GetSignedProposal()
if err != nil {
return shim.Error(fmt.Sprintf("Failed retrieving signed proposal on executing %s with error %s", function, err))
}
switch function {
case INSTALL:
//安装链码
if len(args) < 2 {
return shim.Error(InvalidArgsLenErr(len(args)).Error())
}
// 2. 检查 local MSP Admins 策略
if err = lscc.policyChecker.CheckPolicyNoChannel(mgmt.Admins, sp); err != nil {
return shim.Error(fmt.Sprintf("Authorization for INSTALL has been denied (error-%s)", err))
}
depSpec := args[1]
// 调用安装执行
err := lscc.executeInstall(stub, depSpec)
if err != nil {
return shim.Error(err.Error())
}
// 返回结果
return shim.Success([]byte("OK"))
}
}
包括状态数据库,安装到本地文件系统后,
// 安装链码 peer chaincode install
func (lscc *lifeCycleSysCC) executeInstall(stub shim.ChaincodeStubInterface, ccbytes []byte) error {
ccpack, err := ccprovider.GetCCPackage(ccbytes)
if err != nil {
return err
}
cds := ccpack.GetDepSpec()
if cds == nil {
return fmt.Errorf("nil deployment spec from from the CC package")
}
//检查链码名称
if err = lscc.isValidChaincodeName(cds.ChaincodeSpec.ChaincodeId.Name); err != nil {
return err
}
//检查版本
if err = lscc.isValidChaincodeVersion(cds.ChaincodeSpec.ChaincodeId.Name, cds.ChaincodeSpec.ChaincodeId.Version); err != nil {
return err
}
// Get any statedb artifacts from the chaincode package, e.g. couchdb index definitions
//解压状态db数据
statedbArtifactsTar, err := ccprovider.ExtractStatedbArtifactsFromCCPackage(ccpack)
if err != nil {
return err
}
if err = isValidStatedbArtifactsTar(statedbArtifactsTar); err != nil {
return InvalidStatedbArtifactsErr(err.Error())
}
chaincodeDefinition := &cceventmgmt.ChaincodeDefinition{
Name: ccpack.GetChaincodeData().Name,
Version: ccpack.GetChaincodeData().Version,
Hash: ccpack.GetId()} // Note - The chaincode 'id' is the hash of chaincode's (CodeHash || MetaDataHash), aka fingerprint
// HandleChaincodeInstall will apply any statedb artifacts (e.g. couchdb indexes) to
// any channel's statedb where the chaincode is already instantiated
// Note - this step is done prior to PutChaincodeToLocalStorage() since this step is idempotent and harmless until endorsements start,
// that is, if there are errors deploying the indexes the chaincode install can safely be re-attempted later.
//处理安装,含有db数据
err = cceventmgmt.GetMgr().HandleChaincodeInstall(chaincodeDefinition, statedbArtifactsTar)
if err != nil {
return err
}
//安装到本地文件系统
if err = lscc.support.PutChaincodeToLocalStorage(ccpack); err != nil {
return err
}
logger.Infof("Installed Chaincode [%s] Version [%s] to peer", ccpack.GetChaincodeData().Name, ccpack.GetChaincodeData().Version)
return nil
}