code: func ValidateCip(baseCip, otherCip *peer.SignedChaincodeDeploymentSpec) error {
  	if baseCip == nil || otherCip == nil {
  		panic("do not call with nil parameters")
  	}
  
  	if (baseCip.OwnerEndorsements == nil && otherCip.OwnerEndorsements != nil) || (baseCip.OwnerEndorsements != nil && otherCip.OwnerEndorsements == nil) {
  		return fmt.Errorf("endorsements should either be both nil or not nil")
  	}
  
  	bN := len(baseCip.OwnerEndorsements)
  	oN := len(otherCip.OwnerEndorsements)
  	if bN > 1 || oN > 1 {
  		return fmt.Errorf("expect utmost 1 endorsement from a owner")
  	}
  
  	if bN != oN {
  		return fmt.Errorf("Rule-all packages should be endorsed or none should be endorsed failed for (%d, %d)", bN, oN)
  	}
  
  	if !bytes.Equal(baseCip.ChaincodeDeploymentSpec, otherCip.ChaincodeDeploymentSpec) {
  		return fmt.Errorf("Rule-all deployment specs should match(%d, %d)", len(baseCip.ChaincodeDeploymentSpec), len(otherCip.ChaincodeDeploymentSpec))
  	}
  
  	if !bytes.Equal(baseCip.InstantiationPolicy, otherCip.InstantiationPolicy) {
  		return fmt.Errorf("Rule-all instantiation policies should match(%d, %d)", len(baseCip.InstantiationPolicy), len(otherCip.InstantiationPolicy))
  	}
  
  	return nil
  }
docs: // This file provides functions for helping with the chaincode install
  // package workflow. In particular
  //     OwnerCreateSignedCCDepSpec - each owner creates signs the package using the same deploy
  //     CreateSignedCCDepSpecForInstall - an admin or owner creates the package to be installed
  //                                       using the packages from OwnerCreateSignedCCDepSpec
  // ValidateCip validate the endorsed package against the base package