privateledger

A Hyperledger Fabric Private Data Store in Multi Org Network, written in Go Fabric SDK

MIT License

Stars
14

./bin/cryptogen generate --config=./crypto-config.yaml

./bin/configtxgen -profile FourOrgsOrdererGenesis -outputBlock ./artifacts/orderer.genesis.block

./bin/configtxgen -profile FourOrgsChannel -outputCreateChannelTx ./artifacts/privateledger.channel.tx -channelID privateledger

./bin/configtxgen -profile FourOrgsChannel -outputAnchorPeersUpdate ./artifacts/Org1MSPanchors.tx -channelID privateledger -asOrg Org1MSP

./bin/configtxgen -profile FourOrgsChannel -outputAnchorPeersUpdate ./artifacts/Org2MSPanchors.tx -channelID privateledger -asOrg Org2MSP

./bin/configtxgen -profile FourOrgsChannel -outputAnchorPeersUpdate ./artifacts/Org3MSPanchors.tx -channelID privateledger -asOrg Org3MSP

./bin/configtxgen -profile FourOrgsChannel -outputAnchorPeersUpdate ./artifacts/Org4MSPanchors.tx -channelID privateledger -asOrg Org4MSP

req := resmgmt.SaveChannelRequest{
    ChannelID: "multiorgledger", 
    ChannelConfigPath: os.os.Getenv("GOPATH")+"/multiorgledger.channel.tx", 
    SigningIdentities: []msp.SigningIdentity{Org1SignIdentity, Org2SignIdentity, Org3SignIdentity, Org4SignIdentity},
}

txID, err := s.Resmgmt.SaveChannel(
    req, resmgmt.WithOrdererEndpoint(Orderer.OrdererID))

if err != nil || txID.TransactionID == "" {
    return errors.WithMessage(err, "failed to save anchor channel for - "+s.OrgName)
}
    req := resmgmt.SaveChannelRequest{
           ChannelID: "multiorgledger", 
           ChannelConfigPath: os.os.Getenv("GOPATH")+"/", //Org1MSPanchors.tx or Org2MSPanchors.tx or Org3MSPanchors.tx or Org4MSPanchors.tx
            SigningIdentities: []msp.SigningIdentity{Org1SignIdentity or Org2SignIdentity or Org3SignIdentity or Org4SignIdentity},
    }

    txID, err := s.Resmgmt.SaveChannel(
            req, resmgmt.WithOrdererEndpoint(Orderer.OrdererID))

    if err != nil || txID.TransactionID == "" {
            return errors.WithMessage(err, "failed to save anchor channel for - "+s.OrgName)
     }

if err := s.Resmgmt.JoinChannel(s.ChannelID, resmgmt.WithRetry(retry.DefaultResMgmtOpts), resmgmt.WithOrdererEndpoint(Orderer.OrdererID)); err != nil { return errors.WithMessage(err, "failed to make admin join channel") }

    resp, err := orgResmgmt.QueryChannels(resmgmt.WithTargets(peer))
    if err != nil {
          fmt.Println("IsJoinedChannel : failed to Query >>> "+err.Error())
          return false, err
    }

    for _, chInfo := range resp.Channels {
          fmt.Println("IsJoinedChannel : "+chInfo.ChannelId+" --- "+s.ChannelID)
           if chInfo.ChannelId == s.ChannelID {
                    return true, nil
            }
    }
    req := resmgmt.InstallCCRequest{
            Name:    s.ChaincodeId,
            Path:    s.ChaincodePath,
            Version: s.ChainCodeVersion,
            Package: ccPkg,
    }

    _, err = s.Resmgmt.InstallCC(req,
            resmgmt.WithRetry(retry.DefaultResMgmtOpts))

    if err != nil {
       fmt.Println("failed to install chaincode : "+err.Error())
       return errors.WithMessage(err, "  failed to install chaincode")
    }
  Policy : "OR ('Org1MSP.member')"
func newCollectionConfig(colName, policy string, reqPeerCount, maxPeerCount int32, blockToLive uint64) (*cb.CollectionConfig, error) {

        p, err := cauthdsl.FromString(policy)

    	if err != nil {
            fmt.Println("failed to create newCollectionConfig : "+err.Error())
            return nil, err
        }
        cpc := &cb.CollectionPolicyConfig{
            Payload: &cb.CollectionPolicyConfig_SignaturePolicy{
                SignaturePolicy: p,
            },
        }
        return &cb.CollectionConfig{
            Payload: &cb.CollectionConfig_StaticCollectionConfig{
                StaticCollectionConfig: &cb.StaticCollectionConfig{
                    Name:              colName,
                    MemberOrgsPolicy:  cpc,
                    RequiredPeerCount: reqPeerCount,
                    MaximumPeerCount:  maxPeerCount,
                    BlockToLive:       blockToLive,
                },
            },
        }, nil
}

// The maximum no of block allocated to keep private data alive, after that the data will purge across the network 
blockToLive = 1000 

// Number of peer required to distribute the private data as a condition of the endorsement of the chaincode peerCount = 0 // This is the maxium number of peers allocated to a collection, if an endorsing peer goes down, then other peers are available maximumPeerCount = 3

collCfg1, _ := newCollectionConfig("collectionOrg1", "OR ('Org1MSP.member')", peerCount, maximumPeerCount, blockToLive) collCfg2, _ := newCollectionConfig("collectionOrg2", "OR ('Org2MSP.member')", peerCount, maximumPeerCount, blockToLive) collCfg3, _ := newCollectionConfig("collectionOrg3", "OR ('Org3MSP.member')", peerCount, maximumPeerCount, blockToLive) collCfg4, _ := newCollectionConfig("collectionOrg4", "OR ('Org4MSP.member')", peerCount, maximumPeerCount, blockToLive)

cfg := []*cb.CollectionConfig{ collCfg1, collCfg2, collCfg3, collCfg4}
policy = "OR ('Org1MSP.member','Org2MSP.member','Org3MSP.member','Org4MSP.member')"     

ccPolicy, _ := cauthdsl.FromString(policy) // cauthdsl will convert the policy string to Policy object

resp, err := s.Resmgmt.InstantiateCC(
    s.ChannelID,
    resmgmt.InstantiateCCRequest{
       
        Name:       s.ChaincodeId,
        Path:       s.ChaincodePath,
        Version:    s.ChainCodeVersion,
        Args:       [][]byte{[]byte("init")},
        Policy:     ccPolicy,
        CollConfig: cfg,

},resmgmt.WithRetry(retry.DefaultResMgmtOpts), resmgmt.WithTargets(orgPeers[0], orgPeers[1]))
req := resmgmt.UpgradeCCRequest{
  Name: 	      s.ChaincodeId, 
  Version: 	    s.ChainCodeVersion, 
  Path: 	      s.ChaincodePath, 
  Args:  	      [][]byte{[]byte("init")},
  Policy: 	    ccPolicy,
  CollConfig:   cfg,    
}

resp, err := s.Resmgmt.UpgradeCC(s.ChannelID, req, resmgmt.WithRetry(retry.DefaultResMgmtOpts),resmgmt.WithTargets(orgPeers[0], orgPeers[1]))

if err != nil {
  return errors.WithMessage(err, " >>>> failed to upgrade chaincode")
}
  resp, err := resMgmt.QueryInstalledChaincodes(resmgmt.WithTargets(peer))

  if err != nil {
     return false, errors.WithMessage(err, "  QueryInstalledChaincodes for peer [%s] failed : "+peer.URL())
  }
  found := false

  for _, ccInfo := range resp.Chaincodes {
      fmt.Println("   "+orgID+" found chaincode "+ccInfo.Name+" --- "+ccName+ " with version "+ ccInfo.Version+" -- "+ccVersion)
  		if ccInfo.Name == ccName && ccInfo.Version == ccVersion {
          found = true
          break
     }
  }

  if !found {
  		fmt.Println("   "+orgID+" chaincode is not installed on peer "+ peer.URL())
        installedOnAllPeers = false
  }  
	chaincodeQueryResponse, err := resMgmt.QueryInstantiatedChaincodes(channelID, resmgmt.WithRetry(retry.DefaultResMgmtOpts),    resmgmt.WithTargets(peer))

	    if err != nil {
	        return false, errors.WithMessage(err, "  QueryInstantiatedChaincodes return error")
	    }
	    fmt.Println("\n   Found instantiated chaincodes on peer "+peer.URL())

	    found := false

	    for _, chaincode := range chaincodeQueryResponse.Chaincodes {
	        fmt.Println("   Found instantiated chaincode Name: "+chaincode.Name+", Version: "+chaincode.Version+", Path: "+chaincode.Path+" on peer "+peer.URL())
	        if chaincode.Name == ccName && chaincode.Version == ccVersion {
	            found = true
	            break
	        }
	   }

	    if !found {
	        fmt.Println("  "+ccName+" chaincode is not instantiated on peer "+ peer.URL())
	        installedOnAllPeers = false
	    } 
	// to perform the query individual org ca client needs to be used  

	affl := strings.ToLower(org) + ".department1"

	_, err = caClient.AddAffiliation(&caMsp.AffiliationRequest{

	      Name:   affl,
	      Force:  true,
	      CAName: caid,
	})

	if err != nil {
		return fmt.Errorf("Failed to add affiliation for CA '%s' : %v ", caid, err)
	}
	fRes, err := caClient.GetAffiliation(affl)

	if afRes != nil && err != nil {

		  fmt.Println("Affiliation Exists")

		  AfInfo := afRes.AffiliationInfo
		  CAName := afRes.CAName

		  fmt.Println("AfInfo : " + AfInfo.Name)
		  fmt.Println("CAName : " + CAName)
	}

PrivateLedger - https://www.dropbox.com/s/ry1jmw0y9xliose/vendor.zip?dl=0

Chaincode - https://www.dropbox.com/s/31nnqflpqwaywoa/vendor.zip?dl=0