github.com/osdi23p228/fabric@v0.0.0-20221218062954-77808885f5db/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 switch parameters[0] { 124 case "pub": 125 epBytes, err = stub.GetStateValidationParameter("pub") 126 case "priv": 127 epBytes, err = stub.GetPrivateDataValidationParameter("col", "priv") 128 default: 129 return shim.Error("Unknown key specified") 130 } 131 if err != nil { 132 return shim.Error(err.Error()) 133 } 134 135 ep, err := statebased.NewStateEP(epBytes) 136 if err != nil { 137 return shim.Error(err.Error()) 138 } 139 140 // delete organizations from the endorsement policy of that key 141 ep.DelOrgs(parameters...) 142 epBytes, err = ep.Policy() 143 if err != nil { 144 return shim.Error(err.Error()) 145 } 146 147 // set the modified endorsement policy for the key 148 if parameters[0] == "pub" { 149 err = stub.SetStateValidationParameter("pub", epBytes) 150 } else if parameters[0] == "priv" { 151 err = stub.SetPrivateDataValidationParameter("col", "priv", epBytes) 152 } 153 if err != nil { 154 return shim.Error(err.Error()) 155 } 156 157 return shim.Success([]byte{}) 158 } 159 160 // listOrgs returns the list of organizations currently part of 161 // the state's endorsement policy 162 func listOrgs(stub shim.ChaincodeStubInterface) pb.Response { 163 _, parameters := stub.GetFunctionAndParameters() 164 if len(parameters) < 1 { 165 return shim.Error("No key specified") 166 } 167 168 // get the endorsement policy for the key 169 var epBytes []byte 170 var err error 171 switch parameters[0] { 172 case "pub": 173 epBytes, err = stub.GetStateValidationParameter("pub") 174 case "priv": 175 epBytes, err = stub.GetPrivateDataValidationParameter("col", "priv") 176 default: 177 return shim.Error("Unknown key specified") 178 } 179 if err != nil { 180 return shim.Error(err.Error()) 181 } 182 183 ep, err := statebased.NewStateEP(epBytes) 184 if err != nil { 185 return shim.Error(err.Error()) 186 } 187 188 // get the list of organizations in the endorsement policy 189 orgs := ep.ListOrgs() 190 orgsList, err := json.Marshal(orgs) 191 if err != nil { 192 return shim.Error(err.Error()) 193 } 194 195 return shim.Success(orgsList) 196 } 197 198 // delEP deletes the state-based endorsement policy for the key altogether 199 func delEP(stub shim.ChaincodeStubInterface) pb.Response { 200 _, parameters := stub.GetFunctionAndParameters() 201 if len(parameters) < 1 { 202 return shim.Error("No key specified") 203 } 204 205 // set the modified endorsement policy for the key to nil 206 var err error 207 if parameters[0] == "pub" { 208 err = stub.SetStateValidationParameter("pub", nil) 209 } else if parameters[0] == "priv" { 210 err = stub.SetPrivateDataValidationParameter("col", "priv", nil) 211 } else { 212 return shim.Error("Unknown key specified") 213 } 214 if err != nil { 215 return shim.Error(err.Error()) 216 } 217 218 return shim.Success([]byte{}) 219 } 220 221 // setVal sets the value of the KVS key 222 func setVal(stub shim.ChaincodeStubInterface) pb.Response { 223 args := stub.GetArgs() 224 if len(args) != 3 { 225 return shim.Error("setval expects two arguments") 226 } 227 var err error 228 if string(args[1]) == "pub" { 229 err = stub.PutState("pub", args[2]) 230 } else if string(args[1]) == "priv" { 231 err = stub.PutPrivateData("col", "priv", args[2]) 232 } else { 233 return shim.Error("Unknown key specified") 234 } 235 if err != nil { 236 return shim.Error(err.Error()) 237 } 238 return shim.Success([]byte{}) 239 } 240 241 // getVal retrieves the value of the KVS key 242 func getVal(stub shim.ChaincodeStubInterface) pb.Response { 243 args := stub.GetArgs() 244 if len(args) != 2 { 245 return shim.Error("No key specified") 246 } 247 var err error 248 var val []byte 249 if string(args[1]) == "pub" { 250 val, err = stub.GetState("pub") 251 } else if string(args[1]) == "priv" { 252 val, err = stub.GetPrivateData("col", "priv") 253 } else { 254 return shim.Error("Unknown key specified") 255 } 256 if err != nil { 257 return shim.Error(err.Error()) 258 } 259 260 return shim.Success(val) 261 } 262 263 // invokeCC is used for chaincode to chaincode invocation of a given cc on another channel 264 func invokeCC(stub shim.ChaincodeStubInterface) pb.Response { 265 args := stub.GetArgs() 266 if len(args) < 3 { 267 return shim.Error("cc2cc expects at least two arguments (channel and chaincode)") 268 } 269 channel := string(args[1]) 270 cc := string(args[2]) 271 nargs := args[3:] 272 resp := stub.InvokeChaincode(cc, nargs, channel) 273 return resp 274 }