github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/integration/chaincode/keylevelep/chaincode.go (about)

     1  /*
     2  Copyright hechain. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package keylevelep
     8  
     9  import (
    10  	"encoding/json"
    11  	"fmt"
    12  
    13  	"github.com/hyperledger/fabric-chaincode-go/pkg/statebased"
    14  	"github.com/hyperledger/fabric-chaincode-go/shim"
    15  	pb "github.com/hyperledger/fabric-protos-go/peer"
    16  )
    17  
    18  /*
    19  EndorsementCC is an example chaincode that uses state-based endorsement.
    20  In the init function, it creates two KVS states, one public, one private, that
    21  can then be modified through chaincode functions that use the state-based
    22  endorsement chaincode convenience layer. The following chaincode functions
    23  are provided:
    24  -) "addorgs": supply a list of MSP IDs that will be added to the
    25     state's endorsement policy
    26  -) "delorgs": supply a list of MSP IDs that will be removed from
    27     the state's endorsement policy
    28  -) "delep": delete the key-level endorsement policy for the state altogether
    29  -) "listorgs": list the orgs included in the state's endorsement policy
    30  */
    31  type EndorsementCC struct{}
    32  
    33  // Init callback
    34  func (cc *EndorsementCC) Init(stub shim.ChaincodeStubInterface) pb.Response {
    35  	err := stub.PutState("pub", []byte("foo"))
    36  	if err != nil {
    37  		return shim.Error(err.Error())
    38  	}
    39  	return shim.Success(nil)
    40  }
    41  
    42  // Invoke dispatcher
    43  func (cc *EndorsementCC) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
    44  	funcName, _ := stub.GetFunctionAndParameters()
    45  	if function, ok := functions[funcName]; ok {
    46  		return function(stub)
    47  	}
    48  	return shim.Error(fmt.Sprintf("Unknown function %s", funcName))
    49  }
    50  
    51  // function dispatch map used by Invoke()
    52  var functions = map[string]func(stub shim.ChaincodeStubInterface) pb.Response{
    53  	"addorgs":  addOrgs,
    54  	"delorgs":  delOrgs,
    55  	"listorgs": listOrgs,
    56  	"delep":    delEP,
    57  	"setval":   setVal,
    58  	"getval":   getVal,
    59  	"cc2cc":    invokeCC,
    60  }
    61  
    62  // addOrgs adds the list of MSP IDs from the invocation parameters
    63  // to the state's endorsement policy
    64  func addOrgs(stub shim.ChaincodeStubInterface) pb.Response {
    65  	_, parameters := stub.GetFunctionAndParameters()
    66  	if len(parameters) < 2 {
    67  		return shim.Error("No orgs to add specified")
    68  	}
    69  
    70  	// get the endorsement policy for the key
    71  	var epBytes []byte
    72  	var err error
    73  	if parameters[0] == "pub" {
    74  		epBytes, err = stub.GetStateValidationParameter("pub")
    75  	} else if parameters[0] == "priv" {
    76  		epBytes, err = stub.GetPrivateDataValidationParameter("col", "priv")
    77  	} else {
    78  		return shim.Error("Unknown key specified")
    79  	}
    80  	if err != nil {
    81  		return shim.Error(err.Error())
    82  	}
    83  	ep, err := statebased.NewStateEP(epBytes)
    84  	if err != nil {
    85  		return shim.Error(err.Error())
    86  	}
    87  
    88  	// add organizations to endorsement policy
    89  	err = ep.AddOrgs(statebased.RoleTypePeer, parameters[1:]...)
    90  	if err != nil {
    91  		return shim.Error(err.Error())
    92  	}
    93  	epBytes, err = ep.Policy()
    94  	if err != nil {
    95  		return shim.Error(err.Error())
    96  	}
    97  
    98  	// set the modified endorsement policy for the key
    99  	if parameters[0] == "pub" {
   100  		err = stub.SetStateValidationParameter("pub", epBytes)
   101  	} else if parameters[0] == "priv" {
   102  		err = stub.SetPrivateDataValidationParameter("col", "priv", epBytes)
   103  	}
   104  	if err != nil {
   105  		return shim.Error(err.Error())
   106  	}
   107  
   108  	return shim.Success([]byte{})
   109  }
   110  
   111  // delOrgs removes the list of MSP IDs from the invocation parameters
   112  // from the state's endorsement policy
   113  func delOrgs(stub shim.ChaincodeStubInterface) pb.Response {
   114  	_, parameters := stub.GetFunctionAndParameters()
   115  	if len(parameters) < 2 {
   116  		return shim.Error("No orgs to delete specified")
   117  	}
   118  
   119  	// get the endorsement policy for the key
   120  	var epBytes []byte
   121  	var err error
   122  	switch parameters[0] {
   123  	case "pub":
   124  		epBytes, err = stub.GetStateValidationParameter("pub")
   125  	case "priv":
   126  		epBytes, err = stub.GetPrivateDataValidationParameter("col", "priv")
   127  	default:
   128  		return shim.Error("Unknown key specified")
   129  	}
   130  	if err != nil {
   131  		return shim.Error(err.Error())
   132  	}
   133  
   134  	ep, err := statebased.NewStateEP(epBytes)
   135  	if err != nil {
   136  		return shim.Error(err.Error())
   137  	}
   138  
   139  	// delete organizations from the endorsement policy of that key
   140  	ep.DelOrgs(parameters...)
   141  	epBytes, err = ep.Policy()
   142  	if err != nil {
   143  		return shim.Error(err.Error())
   144  	}
   145  
   146  	// set the modified endorsement policy for the key
   147  	if parameters[0] == "pub" {
   148  		err = stub.SetStateValidationParameter("pub", epBytes)
   149  	} else if parameters[0] == "priv" {
   150  		err = stub.SetPrivateDataValidationParameter("col", "priv", epBytes)
   151  	}
   152  	if err != nil {
   153  		return shim.Error(err.Error())
   154  	}
   155  
   156  	return shim.Success([]byte{})
   157  }
   158  
   159  // listOrgs returns the list of organizations currently part of
   160  // the state's endorsement policy
   161  func listOrgs(stub shim.ChaincodeStubInterface) pb.Response {
   162  	_, parameters := stub.GetFunctionAndParameters()
   163  	if len(parameters) < 1 {
   164  		return shim.Error("No key specified")
   165  	}
   166  
   167  	// get the endorsement policy for the key
   168  	var epBytes []byte
   169  	var err error
   170  	switch parameters[0] {
   171  	case "pub":
   172  		epBytes, err = stub.GetStateValidationParameter("pub")
   173  	case "priv":
   174  		epBytes, err = stub.GetPrivateDataValidationParameter("col", "priv")
   175  	default:
   176  		return shim.Error("Unknown key specified")
   177  	}
   178  	if err != nil {
   179  		return shim.Error(err.Error())
   180  	}
   181  
   182  	ep, err := statebased.NewStateEP(epBytes)
   183  	if err != nil {
   184  		return shim.Error(err.Error())
   185  	}
   186  
   187  	// get the list of organizations in the endorsement policy
   188  	orgs := ep.ListOrgs()
   189  	orgsList, err := json.Marshal(orgs)
   190  	if err != nil {
   191  		return shim.Error(err.Error())
   192  	}
   193  
   194  	return shim.Success(orgsList)
   195  }
   196  
   197  // delEP deletes the state-based endorsement policy for the key altogether
   198  func delEP(stub shim.ChaincodeStubInterface) pb.Response {
   199  	_, parameters := stub.GetFunctionAndParameters()
   200  	if len(parameters) < 1 {
   201  		return shim.Error("No key specified")
   202  	}
   203  
   204  	// set the modified endorsement policy for the key to nil
   205  	var err error
   206  	if parameters[0] == "pub" {
   207  		err = stub.SetStateValidationParameter("pub", nil)
   208  	} else if parameters[0] == "priv" {
   209  		err = stub.SetPrivateDataValidationParameter("col", "priv", nil)
   210  	} else {
   211  		return shim.Error("Unknown key specified")
   212  	}
   213  	if err != nil {
   214  		return shim.Error(err.Error())
   215  	}
   216  
   217  	return shim.Success([]byte{})
   218  }
   219  
   220  // setVal sets the value of the KVS key
   221  func setVal(stub shim.ChaincodeStubInterface) pb.Response {
   222  	args := stub.GetArgs()
   223  	if len(args) != 3 {
   224  		return shim.Error("setval expects two arguments")
   225  	}
   226  	var err error
   227  	if string(args[1]) == "pub" {
   228  		err = stub.PutState("pub", args[2])
   229  	} else if string(args[1]) == "priv" {
   230  		err = stub.PutPrivateData("col", "priv", args[2])
   231  	} else if string(args[1]) == "both" {
   232  		err = stub.PutState("pub", args[2])
   233  		if err != nil {
   234  			return shim.Error(err.Error())
   235  		}
   236  		err = stub.PutPrivateData("col", "priv", args[2])
   237  	} else {
   238  		return shim.Error("Unknown key specified")
   239  	}
   240  	if err != nil {
   241  		return shim.Error(err.Error())
   242  	}
   243  	return shim.Success([]byte{})
   244  }
   245  
   246  // getVal retrieves the value of the KVS key
   247  func getVal(stub shim.ChaincodeStubInterface) pb.Response {
   248  	args := stub.GetArgs()
   249  	if len(args) != 2 {
   250  		return shim.Error("No key specified")
   251  	}
   252  	var err error
   253  	var val []byte
   254  	if string(args[1]) == "pub" {
   255  		val, err = stub.GetState("pub")
   256  	} else if string(args[1]) == "priv" {
   257  		val, err = stub.GetPrivateData("col", "priv")
   258  	} else {
   259  		return shim.Error("Unknown key specified")
   260  	}
   261  	if err != nil {
   262  		return shim.Error(err.Error())
   263  	}
   264  
   265  	return shim.Success(val)
   266  }
   267  
   268  // invokeCC is used for chaincode to chaincode invocation of a given cc on another channel
   269  func invokeCC(stub shim.ChaincodeStubInterface) pb.Response {
   270  	args := stub.GetArgs()
   271  	if len(args) < 3 {
   272  		return shim.Error("cc2cc expects at least two arguments (channel and chaincode)")
   273  	}
   274  	channel := string(args[1])
   275  	cc := string(args[2])
   276  	nargs := args[3:]
   277  	resp := stub.InvokeChaincode(cc, nargs, channel)
   278  	return resp
   279  }