github.com/lzy4123/fabric@v2.1.1+incompatible/integration/chaincode/keylevelep/chaincode.go (about)

     1  /*
     2  Copyright IBM Corp. 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  
    34  // Init callback
    35  func (cc *EndorsementCC) Init(stub shim.ChaincodeStubInterface) pb.Response {
    36  	err := stub.PutState("pub", []byte("foo"))
    37  	if err != nil {
    38  		return shim.Error(err.Error())
    39  	}
    40  	return shim.Success(nil)
    41  }
    42  
    43  // Invoke dispatcher
    44  func (cc *EndorsementCC) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
    45  	funcName, _ := stub.GetFunctionAndParameters()
    46  	if function, ok := functions[funcName]; ok {
    47  		return function(stub)
    48  	}
    49  	return shim.Error(fmt.Sprintf("Unknown function %s", funcName))
    50  }
    51  
    52  // function dispatch map used by Invoke()
    53  var functions = map[string]func(stub shim.ChaincodeStubInterface) pb.Response{
    54  	"addorgs":  addOrgs,
    55  	"delorgs":  delOrgs,
    56  	"listorgs": listOrgs,
    57  	"delep":    delEP,
    58  	"setval":   setVal,
    59  	"getval":   getVal,
    60  	"cc2cc":    invokeCC,
    61  }
    62  
    63  // addOrgs adds the list of MSP IDs from the invocation parameters
    64  // to the state's endorsement policy
    65  func addOrgs(stub shim.ChaincodeStubInterface) pb.Response {
    66  	_, parameters := stub.GetFunctionAndParameters()
    67  	if len(parameters) < 2 {
    68  		return shim.Error("No orgs to add specified")
    69  	}
    70  
    71  	// get the endorsement policy for the key
    72  	var epBytes []byte
    73  	var err error
    74  	if parameters[0] == "pub" {
    75  		epBytes, err = stub.GetStateValidationParameter("pub")
    76  	} else if parameters[0] == "priv" {
    77  		epBytes, err = stub.GetPrivateDataValidationParameter("col", "priv")
    78  	} else {
    79  		return shim.Error("Unknown key specified")
    80  	}
    81  	if err != nil {
    82  		return shim.Error(err.Error())
    83  	}
    84  	ep, err := statebased.NewStateEP(epBytes)
    85  	if err != nil {
    86  		return shim.Error(err.Error())
    87  	}
    88  
    89  	// add organizations to endorsement policy
    90  	err = ep.AddOrgs(statebased.RoleTypePeer, parameters[1:]...)
    91  	if err != nil {
    92  		return shim.Error(err.Error())
    93  	}
    94  	epBytes, err = ep.Policy()
    95  	if err != nil {
    96  		return shim.Error(err.Error())
    97  	}
    98  
    99  	// set the modified endorsement policy for the key
   100  	if parameters[0] == "pub" {
   101  		err = stub.SetStateValidationParameter("pub", epBytes)
   102  	} else if parameters[0] == "priv" {
   103  		err = stub.SetPrivateDataValidationParameter("col", "priv", epBytes)
   104  	}
   105  	if err != nil {
   106  		return shim.Error(err.Error())
   107  	}
   108  
   109  	return shim.Success([]byte{})
   110  }
   111  
   112  // delOrgs removes the list of MSP IDs from the invocation parameters
   113  // from the state's endorsement policy
   114  func delOrgs(stub shim.ChaincodeStubInterface) pb.Response {
   115  	_, parameters := stub.GetFunctionAndParameters()
   116  	if len(parameters) < 2 {
   117  		return shim.Error("No orgs to delete specified")
   118  	}
   119  
   120  	// get the endorsement policy for the key
   121  	var epBytes []byte
   122  	var err error
   123  	if parameters[0] == "pub" {
   124  		epBytes, err = stub.GetStateValidationParameter("pub")
   125  	} else if parameters[0] == "priv" {
   126  		epBytes, err = stub.GetPrivateDataValidationParameter("col", "priv")
   127  	} else {
   128  		return shim.Error("Unknown key specified")
   129  	}
   130  	ep, err := statebased.NewStateEP(epBytes)
   131  	if err != nil {
   132  		return shim.Error(err.Error())
   133  	}
   134  
   135  	// delete organizations from the endorsement policy of that key
   136  	ep.DelOrgs(parameters...)
   137  	epBytes, err = ep.Policy()
   138  	if err != nil {
   139  		return shim.Error(err.Error())
   140  	}
   141  
   142  	// set the modified endorsement policy for the key
   143  	if parameters[0] == "pub" {
   144  		err = stub.SetStateValidationParameter("pub", epBytes)
   145  	} else if parameters[0] == "priv" {
   146  		err = stub.SetPrivateDataValidationParameter("col", "priv", epBytes)
   147  	}
   148  	if err != nil {
   149  		return shim.Error(err.Error())
   150  	}
   151  
   152  	return shim.Success([]byte{})
   153  }
   154  
   155  // listOrgs returns the list of organizations currently part of
   156  // the state's endorsement policy
   157  func listOrgs(stub shim.ChaincodeStubInterface) pb.Response {
   158  	_, parameters := stub.GetFunctionAndParameters()
   159  	if len(parameters) < 1 {
   160  		return shim.Error("No key specified")
   161  	}
   162  
   163  	// get the endorsement policy for the key
   164  	var epBytes []byte
   165  	var err error
   166  	if parameters[0] == "pub" {
   167  		epBytes, err = stub.GetStateValidationParameter("pub")
   168  	} else if parameters[0] == "priv" {
   169  		epBytes, err = stub.GetPrivateDataValidationParameter("col", "priv")
   170  	} else {
   171  		return shim.Error("Unknown key specified")
   172  	}
   173  	ep, err := statebased.NewStateEP(epBytes)
   174  	if err != nil {
   175  		return shim.Error(err.Error())
   176  	}
   177  
   178  	// get the list of organizations in the endorsement policy
   179  	orgs := ep.ListOrgs()
   180  	orgsList, err := json.Marshal(orgs)
   181  	if err != nil {
   182  		return shim.Error(err.Error())
   183  	}
   184  
   185  	return shim.Success(orgsList)
   186  }
   187  
   188  // delEP deletes the state-based endorsement policy for the key altogether
   189  func delEP(stub shim.ChaincodeStubInterface) pb.Response {
   190  	_, parameters := stub.GetFunctionAndParameters()
   191  	if len(parameters) < 1 {
   192  		return shim.Error("No key specified")
   193  	}
   194  
   195  	// set the modified endorsement policy for the key to nil
   196  	var err error
   197  	if parameters[0] == "pub" {
   198  		err = stub.SetStateValidationParameter("pub", nil)
   199  	} else if parameters[0] == "priv" {
   200  		err = stub.SetPrivateDataValidationParameter("col", "priv", nil)
   201  	} else {
   202  		return shim.Error("Unknown key specified")
   203  	}
   204  	if err != nil {
   205  		return shim.Error(err.Error())
   206  	}
   207  
   208  	return shim.Success([]byte{})
   209  }
   210  
   211  // setVal sets the value of the KVS key
   212  func setVal(stub shim.ChaincodeStubInterface) pb.Response {
   213  	args := stub.GetArgs()
   214  	if len(args) != 3 {
   215  		return shim.Error("setval expects two arguments")
   216  	}
   217  	var err error
   218  	if string(args[1]) == "pub" {
   219  		err = stub.PutState("pub", args[2])
   220  	} else if string(args[1]) == "priv" {
   221  		err = stub.PutPrivateData("col", "priv", args[2])
   222  	} else {
   223  		return shim.Error("Unknown key specified")
   224  	}
   225  	if err != nil {
   226  		return shim.Error(err.Error())
   227  	}
   228  	return shim.Success([]byte{})
   229  }
   230  
   231  // getVal retrieves the value of the KVS key
   232  func getVal(stub shim.ChaincodeStubInterface) pb.Response {
   233  	args := stub.GetArgs()
   234  	if len(args) != 2 {
   235  		return shim.Error("No key specified")
   236  	}
   237  	var err error
   238  	var val []byte
   239  	if string(args[1]) == "pub" {
   240  		val, err = stub.GetState("pub")
   241  	} else if string(args[1]) == "priv" {
   242  		val, err = stub.GetPrivateData("col", "priv")
   243  	} else {
   244  		return shim.Error("Unknown key specified")
   245  	}
   246  	if err != nil {
   247  		return shim.Error(err.Error())
   248  	}
   249  
   250  	return shim.Success(val)
   251  }
   252  
   253  // invokeCC is used for chaincode to chaincode invocation of a given cc on another channel
   254  func invokeCC(stub shim.ChaincodeStubInterface) pb.Response {
   255  	args := stub.GetArgs()
   256  	if len(args) < 3 {
   257  		return shim.Error("cc2cc expects at least two arguments (channel and chaincode)")
   258  	}
   259  	channel := string(args[1])
   260  	cc := string(args[2])
   261  	nargs := args[3:]
   262  	resp := stub.InvokeChaincode(cc, nargs, channel)
   263  	return resp
   264  }