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 }