code: func (s *Store) Save(name, version string, ccInstallPkg []byte) ([]byte, error) {
  	metadataJSON, err := toJSON(name, version)
  	if err != nil {
  		return nil, err
  	}
  
  	hash := util.ComputeSHA256(ccInstallPkg)
  	hashString := hex.EncodeToString(hash)
  	metadataPath := filepath.Join(s.Path, hashString+".json")
  	if _, err := s.ReadWriter.Stat(metadataPath); err == nil {
  		return nil, errors.Errorf("chaincode metadata already exists at %s", metadataPath)
  	}
  
  	ccInstallPkgPath := filepath.Join(s.Path, hashString+".bin")
  	if _, err := s.ReadWriter.Stat(ccInstallPkgPath); err == nil {
  		return nil, errors.Errorf("ChaincodeInstallPackage already exists at %s", ccInstallPkgPath)
  	}
  
  	if err := s.ReadWriter.WriteFile(metadataPath, metadataJSON, 0600); err != nil {
  		return nil, errors.Wrapf(err, "error writing metadata file to %s", metadataPath)
  	}
  
  	if err := s.ReadWriter.WriteFile(ccInstallPkgPath, ccInstallPkg, 0600); err != nil {
  		err = errors.Wrapf(err, "error writing chaincode install package to %s", ccInstallPkgPath)
  		logger.Error(err.Error())
  
  		// need to roll back metadata write above on error
  		if err2 := s.ReadWriter.Remove(metadataPath); err2 != nil {
  			logger.Errorf("error removing metadata file at %s: %s", metadataPath, err2)
  		}
  		return nil, err
  	}
  
  	return hash, nil
  }
docs: // Save persists chaincode install package bytes with the given name
  // and version